我试图让Guice在JBoss EAP 6.4上部署的Web应用程序中工作 当我尝试单步执行Guice代码时,我注意到绑定正在发生。但是,当我尝试注入绑定对象时,我总是得到null。以下是我为启用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) MainModule
public class MainModule extends AbstractModule {
@Override
protected void configure() {
install(new BankAccountModule());
install(new CoreModule());
}
}
4) BankAccountModule
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) BankAccountServiceUVS
@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。我已经在几个论坛上倾注了几天无济于事。有人可以指出我缺少的东西吗?
答案 0 :(得分:0)
Guice假定,如果您为一个对象编写了一个Provider,那么您已经注入了该对象,并且它本身并不需要这样做。
在Injections page in the Guice Wiki上,Guice列出了从图形访问已注入对象的方法,但是在大多数情况下,Guice假定它自己在创建这些对象(除了底部的“自动注入”部分,该部分适用于{ {1}}和toInstance
绑定到已创建的实例)。
您的提供者使用toProvider
查找并创建您的BankAccountService,它不会触发Guice的任何注入。因此,您的BankAccountService不会注入其ServiceLocator.locateService
注释的成员。
您的立场上,我会格外谨慎:您已将BankAccountServiceUVS设置为一个显然希望使用依赖项注入框架创建的类</ em>。您的ServiceLocator和Guice注入器有一些重叠的职责,如果有任何非Guice客户注入您的BankAccountServiceUVS,他们将把您的@Inject字段视为@Inject
。我将继续选择以下选项之一,首先选择最优选的选项:
从JNDI中删除BankAccountServiceUVS,并根据需要使用Guice创建它并将其与拦截器一起注入。这适当地反映出,如果没有Guice,Spring或其他@ Inject-aware框架,BankAccountServiceUVS将无法工作。
修改BankAccountService以包含初始化方法,例如null
。这意味着BankAccountService使用者还具有调用该方法的其他要求,但无论实现或依赖项注入框架如何,都允许BankAccountService正常工作。为了获得BankAccountProvider,可以在您的void init(BankAccountProvider accountProvider)
类中添加一个@Inject字段。与BankAccountService不同,BankAccountServiceProvider由Guice和gets automatic access to @Inject fields创建。
修改BankAccountServiceProvider以注入一个注入器,它是default binding in Guice。在对BankAccountServiceProvider
的调用中,从JNDI获得BankAccountService之后,在其上调用Injector.injectMembers(Object)
。通过反思地检查对象实例,这将填充所有get
字段并调用所有@Inject
方法。请注意,这是这三种方法中最直观,最危险的方法,因为Guice检查对象的动态类型(BankAccountServiceUVS),而其他DI框架(如Dagger)将仅检查对象的静态类型(BankAccountService),而不会发现任何东西。在接口上@Inject注释。它还有效地要求BankAccountServiceUVS必须使用类似Guice的DI框架来构建,因为对@Inject
的调用将成功,但是如果Guice不注入对象,则与new BankAccountServiceUVS()
的交互将失败。