我有一个类,我在其中声明了我的静态常量:
public final class ConfigOptions {
public static final String FILE_PATH_SERVER = "/home/user/me/somefile";
}
然后我使用 Guice 在我的 ServletModule
中绑定(bind)它:
public class MyServletModule extends ServletModule {
bind(String.class).annotatedWith(Names.named("filePath"))
.toInstance(ConfigOptions.FILE_PATH_SERVER);
// Also tried
// bindConstant().annotatedWith(Names.named("filePath")).to(ConfigOptions.FILE_PATH_SERVER)
// ... other bindings
}
我的GuiceServletContextListener
:
public class MyServletContextListener extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
return Guice.createInjector(new MyServletModule());
}
}
最后,我尝试使用 filePath
:
public class MyClass {
@Inject
@Named("filePath")
private String filePath;
public MyClass() { ... }
public void doSomething() {
someotherThing.setFilePath(filePath); // But filePath is null
}
}
我主要遵循显示的方法 here但不确定我是否遗漏了什么。
此外,我已确保导入了正确的 import com.google.inject.name.Named
。
最佳答案
确认您是让 Guice 创建您的 MyClass 实例,而不是使用 new MyClass()
自己实例化它们。即使一个字段用 @Inject
标记,如果 Guice 负责创建包含它的实例*,Guice 也只能设置该值。使用您拥有的字段注入(inject),如果从未通过注入(inject)器请求该类,则该字段将静默保持为空。
切换到构造函数注入(inject)也有助于明确该类是否是通过 Guice 提供的,因为更改构造函数本质上会破坏任何直接调用,而不会破坏 Guice 创建的引用:
public class MyClass {
private final String filePath;
@Inject public MyClass(@Named("filePath") String filePath) {
this.filePath = filePath;
// ...
}
// ...
}
*您也可以使用 Injector.injectMembers(instance) 哄骗 Guice 注入(inject)现有实例。或 Binder.requestInjection(instance) .这些并不常见,可能会让人难以追踪您在哪里构造和注入(inject)实例,但在遗留代码和其他一些情况下可能会很有用。
关于java - Guice:用@Named 注释的字段的值为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22084130/