这是我的客户:
class Client {
@Inject(optional=true) Service service;
}
有时候不需要Service,我们知道JVM启动时的信息(即绑定器运行之前)。 如何使绑定可选?如果我根本没有指定绑定,它会尝试新建服务(并且因为没有零参数构造函数而失败:“在package.Client.service(Service.java:40)注入时出错:可能在package.Service。“)中找不到合适的构造函数,我不能这样做:
binder.bind(Service.class).toInstance(null);
因为Guice似乎不允许空值。有什么想法吗?
答案 0 :(得分:7)
您使用的是Guice 2.0吗?我已经尝试了这两个,Service
是一个接口(服务字段总是null
),如果它不能用JIT创建一个新实例,它就是一个类(null
绑定,如果它可以的实例)。两者看起来都像你期望的那样。
在这两种情况下,我都没有使用类似bind(Service.class).toInstance(null)
的绑定。如果这样做,那么您需要确保Service
的所有注入点都指定它们允许null
。这可以通过使用任何名为@Nullable
的注释注释注入点来完成(您可以自己创建或使用现有注释):
class Client {
@Inject @Nullable Service service;
}
答案 1 :(得分:3)
如果要存在绑定可选项,可以使用@Inject(optional = true)
进行字段和方法注入。对于构造函数和其他参数类型注入,必须使用辅助类,例如:
class Foo {
public String hello(Helper helper) {
return Helper.string;
}
private static final class Helper {
@Inject(optional = true) public String string = "";
}
}
请注意,上述内容不允许注入null
,因此Foo#hello永远不会返回null
。如果您确实要允许null
,只需添加@Nullable
注释即可。请记住,除非您为String提供了绑定(对null,否则为其他),否则以下代码将失败:
class Bar {
@Inject @Nullable public String hello(@Nullable String string) {
return string;
}
}
答案 2 :(得分:2)
我无法重现此行为。当我运行此示例代码时,注入器创建并且可选注入不满意。该程序打印null
:
public class OptionalInjections {
static class Service {
public Service(Void v) {} // not injectable
}
static class Client {
@Inject(optional = true) Service service;
}
public static void main(String[] args) {
Injector i = Guice.createInjector();
Client client = i.getInstance(Client.class);
System.out.println(client.service);
}
}
您是否可以在JUnit测试用例中重现此问题并将其提交给Guice issue tracker?