可选使用 Guice 进行绑定以避免用户绑定



遵循OptionalBinder的文档

用于绑定可选值(可选(的 API,可选择使用默认值。 OptionalBinder 履行两个角色:

  1. 它允许框架定义一个注入点,该注入点可能受用户约束,也可能不受用户约束。
  2. 它允许框架提供可由用户更改的默认值。

我正在尝试跟进上面的第一点,我对此进行了以下设置:

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提供绑定?

bind(new TypeLiteral<Reporting<ReportingEvent>>(){}).to(ReportingImpl.class).in(Singleton.class);

是泛型Reporting<ReportingEvent>的绑定,而

OptionalBinder.newOptionalBinder(binder(), Reporting.class);

实际上是指定原始类型,Reporting.相反,您希望将重载用于指定 TypeLiteral arg 的newOptionalBinder,以便在可选请求和绑定中谈论相同的内容:

OptionalBinder.newOptionalBinder(binder(), new TypeLiteral<Reporting<ReportingEvent>>(){});

没有这个,你基本上是在说"任何对报告的绑定都将满足这个要求",即使是像Reporting<Object>这样的东西——如果你绑定了多个,会发生什么?


另一方面,如果你真的想允许任何Reporting类型的绑定(这是你的错误所暗示的,那么相反的事情是错误的:你指定了泛型 impl 而不是绑定到原始Reporting。将 bind(( 调用更改为"这实际上仅适用于原始请求":

bind(Reporting.class).to(ReportingImpl.class).in(Singleton.class);

使用OptionalBinder时,您实际上并没有指定绑定。使用 tryOptionalBinder时,仍需要指定默认绑定:

OptionalBinder.newOptionalBinder(binder(), Reporting.class)
.setDefault()
.to(ReportingImpl.class);

最新更新