OptionalBinding 使用 Guice 避免用户绑定
Posted
技术标签:
【中文标题】OptionalBinding 使用 Guice 避免用户绑定【英文标题】:OptionalBinding using Guice to avoid binding by users 【发布时间】:2020-01-31 11:30:20 【问题描述】:遵循OptionalBinder
的文档
一种用于绑定可选值的 API,可以选择使用默认值。 OptionalBinder 有两个作用:
它允许框架定义一个可能会或可能不会被用户绑定的注入点。 它允许框架提供可由用户更改的默认值。
我正在尝试跟进上面的第一点,为此我有以下设置:
interface Reporting<R> // service to be bind optionally
class InternalServiceImpl implements InternalService
@Inject
Reporting reporting;
... // use this in a method
public class FrameworkModule extends AbstractModule
protected void configure()
OptionalBinder.newOptionalBinder(binder(), Reporting.class);
在用户模块中 (class UserWorkingModule
) 如果我不提供绑定,例如
bind(new TypeLiteral<Reporting<ReportingEvent>>()).to(ReportingImpl.class).in(Singleton.class);
应用程序无法启动并显示以下日志:
1) No implementation for Reporting was bound. while locating Reporting for field at InternalServiceImpl.reporting(InternalServiceImpl.java:21) at FrameworkModule.configure(FrameworkModule.java:55) (via modules: UserWorkingModule -> FrameworkModule)
是否仍然必须在UserWorkingModule
中为Reporting
提供绑定?
【问题讨论】:
在一个问题上,我用最少的代码分享了哪些有效,哪些无效。我不明白投反对票的原因! 【参考方案1】:bind(new TypeLiteral<Reporting<ReportingEvent>>()).to(ReportingImpl.class).in(Singleton.class);
是通用Reporting<ReportingEvent>
的绑定,而
OptionalBinder.newOptionalBinder(binder(), Reporting.class);
实际上是指定原始类型Reporting
。相反,您想使用 newOptionalBinder
和 specifies a TypeLiteral arg 的重载,以便在可选请求和绑定中讨论相同的内容:
OptionalBinder.newOptionalBinder(binder(), new TypeLiteral<Reporting<ReportingEvent>>());
没有这个,你基本上是在说“任何绑定到报告都会满足这个要求”,甚至像Reporting<Object>
这样的东西 - 如果你绑定多个会发生什么?
另一方面,如果你真的想允许任何Reporting
类型的绑定(这是你的错误所暗示的,那么相反的事情是错误的:而不是绑定到原始Reporting
,你指定了而是通用 impl。将 bind() 调用更改为“这实际上仅适用于原始请求”:
bind(Reporting.class).to(ReportingImpl.class).in(Singleton.class);
【讨论】:
感谢您抽出时间来回答。你的意思是说在FrameworkModule
中使用OptionalBinder.newOptionalBinder(binder(), new TypeLiteral<Reporting<ReportingEvent>>());
,我不需要在UserWorkingModule
中绑定?
UserWorkingModule 不在你的问题中,除了堆栈跟踪,所以我真的不能说。这可能是 bind(..).to(..) 调用所在的类的名称吗?如果是这样,您仍然需要在任何一种方法下,但您需要 newOptionalBinder(..) 和 bind(..).to(..) 同意,因为他们现在不同意(并且那些进一步应该同意注入站点,在 InternalServiceImpl 中,也许还有其他)。
是的,我在“如果我不提供诸如“之类的绑定的用户模块中提到,它是放置bind(..).to(..)
的类的名称。我没有得到你说的部分“在任何一种方法下你仍然需要它”。这不是问题中链接的文档点(1)吗?至于我发布的实际问题,我的意思只是 - 是否仍然必须为 UserWorkingModule 中的报告提供绑定?
哦,我明白了-我理解您的问题是在问“为什么我会收到此错误”(答案是“您的代码与您的请求不匹配”),而不是“如果这种方法使它成为可选的,为什么它似乎仍然是必需的”,它有一个单独的答案。我会相应地更新答案。【参考方案2】:
在使用OptionalBinder
时,您实际上并没有指定绑定。使用OptionalBinder
时仍需要指定默认绑定试试:
OptionalBinder.newOptionalBinder(binder(), Reporting.class)
.setDefault()
.to(ReportingImpl.class);
【讨论】:
以上是关于OptionalBinding 使用 Guice 避免用户绑定的主要内容,如果未能解决你的问题,请参考以下文章