guice - Guice 注入在 Web 应用程序中不起作用
问题描述
我试图让 Guice 在部署在 JBoss EAP 6.4 上的 Web 应用程序中工作 当我尝试单步执行 Guice 代码时,我注意到绑定正在发生。但是,当我尝试注入绑定对象时,我总是得到空值。以下是我为启用 Guice 所做的代码更改 -
1) web.xml
<listener>
<listener-class>com.univeris.guice.GuiceConfig</listener-class>
</listener>
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2)GuiceConfig
@Singleton
public class GuiceConfig extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
Injector injector = Guice.createInjector(
new ServletModule() {
@Override
protected void configureServlets() {
serve("/uif/*").with(UIFInitializeServlet.class);
serve("/upm/*").with(IDPServlet.class, ImmutableMap.of("instance-name","upm"));
serve("/uiw/*").with(IDPServlet.class, ImmutableMap.of("instance-name","uiw"));
}
},
new MainModule()
);
return injector;
}
}
3)主模块
public class MainModule extends AbstractModule {
@Override
protected void configure() {
install(new BankAccountModule());
install(new CoreModule());
}
}
4)银行账户模块
public class BankAccountModule extends AbstractModule {
@Override
protected void configure() {
bind(BankAccountProvider.class).toProvider(BankAccountGuiceProvider.class);
bind(BankAccountService.class).toProvider(BankAccountServiceProvider.class);
}
}
5) BankAccountGuiceProvider
public class BankAccountGuiceProvider implements Provider<BankAccountProvider> {
@Override
public BankAccountProvider get() {
return ProviderLocator.locateProvider(BankAccountProvider.class);
}
}
6) BankAccountServiceProvider
public class BankAccountServiceProvider implements Provider<BankAccountService> {
@Override
public BankAccountService get() {
BankAccountService bankAccountService = ServiceLocator.locateService(BankAccountService.class);
return bankAccountService;
}
}
7)银行账户服务UVS
@Stateless
@Interceptors(ServiceInterceptor.class)
public class BankAccountServiceUVS implements BankAccountService {
@Inject
private BankAccountProvider _bankAccountProvider;
@Override
public BankAccountCollection getAllBankAccounts(final Integer entityId, final String entityType) {
BankAccountCollection retVal = _bankAccountProvider.getAllBankAccounts(entityId,
return PojoHelper.cloneObject(retVal);
}
}
_bankAccountProvider始终作为 null 注入。我已经在几个论坛中倾注了几天,但无济于事。有人可以指出我缺少什么吗?
解决方案
Guice 假设如果您为一个对象编写一个 Provider,那么您已经注入了该对象,并且它本身不需要这样做。
在Guice Wiki 的 Injections 页面上,Guice 列出了从图中访问注入对象的方法,但在大多数情况下,Guice 假设它自己创建了这些对象(除了底部的 Automatic Injections 部分,它适用于toInstance
并toProvider
绑定到已经创建的实例)。
您的 Provider 用于ServiceLocator.locateService
查找和创建您的 BankAccountService,这不会触发 Guice 的任何注入。因此,您的 BankAccountService 将不会@Inject
注入其 -annotated 成员。
在你的位置上,我会谨慎行事:你已经将 BankAccountServiceUVS 变成了一个显然希望使用依赖注入框架创建的类。您的 ServiceLocator 和 Guice Injector 有一些重叠的职责,如果任何非 Guice 客户要注入您的 BankAccountServiceUVS,他们会将您的 @Inject 字段视为null
. 我将继续使用其中一个选项,首先使用我最喜欢的选项:
从 JNDI 中删除 BankAccountServiceUVS 并根据需要使用 Guice 创建并使用拦截器注入它。这恰当地反映了 BankAccountServiceUVS 在没有 Guice、Spring 或其他一些@Inject 感知框架的情况下将无法工作。
修改 BankAccountService 以包含一个初始化方法,例如
void init(BankAccountProvider accountProvider)
. 这意味着 BankAccountService 消费者有调用该方法的额外要求,但允许 BankAccountService 工作,而不管实现或依赖注入框架如何。为了获得 BankAccountProvider,你可以在你的BankAccountServiceProvider
类中添加一个 @Inject 字段;与 BankAccountService 不同,BankAccountServiceProvider 由 Guice 创建并自动访问 @Inject 字段。修改 BankAccountServiceProvider 以注入 Injector,这是Guice 中的默认绑定。在调用 中
get
,从 JNDI 获取您的 BankAccountService 后,调用Injector.injectMembers(Object)
它。这将通过反射检查对象实例来填充所有@Inject
字段并调用所有@Inject
方法。请注意,这是这三种方法中最不直观和最危险的,因为 Guice 检查对象的动态类型(BankAccountServiceUVS),而其他 DI 框架(如 Dagger)只会检查对象的静态类型(BankAccountService)而不会找到任何东西@Inject-annotated 在界面上。它还有效地要求使用像 Guice 这样的 DI 框架构建 BankAccountServiceUVS,因为调用new BankAccountServiceUVS()
将成功但与_bankAccountProvider
如果 Guice 不注入对象,将会失败。
推荐阅读
- c# - 如何在 EF 生成的实体上使所有属性虚拟化?
- python - Django ForeignKey 返回 ID 号而不是实际的字符串值,特别是对于基于表单的 request.POST
- python - 如何在不影响其余部分的情况下延迟我的程序的一部分?
- javascript - 使用 JavaScript 按其类隐藏 li 的元素
- c++ - 模板问题
- vb.net - 如何限制一次产生的进程数?
- python - 在 Windows 上将 python 3.8 降级为 3.7 后如何在 PyCharm 中配置解释器?
- excel - 导出为 PDF 时,冻结的窗格会被部分裁剪
- java - 避免在 XML 中使用 Transformer 写入输出文件
- javascript - 如何在父组件中获取渲染的子组件?