Guice注入在Web应用程序中不起作用

时间:2018-06-18 15:13:26

标签: guice

我试图让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。我已经在几个论坛上倾注了几天无济于事。有人可以指出我缺少的东西吗?

1 个答案:

答案 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()的交互将失败。