将依赖项注入Guice模块

a p*_*a p 6 java dependency-injection guice java-8

我有一个获取并保存API令牌的模块(简化):

@Singleton
public class KeyHolderModule extends AbstractModule {
    // This doesn't seem to be injected
    private @Inject TokenConnector connector;
    private DateTime keyLastRefreshed;
    private String key;
    private Credentials creds = config.getCreds();

    @Override protected void configure() {
        this.key = connector.getToken(creds);
        this.keyLastRefreshed = DateTime.now();
    }

    @Provides @Named("apiKey") public String getKey() {
        // logic to check key last refreshed and handle generating a new one
        return this.key;
    }
}
Run Code Online (Sandbox Code Playgroud)

我在尝试访问连接器(this.key = connector.getToken(creds);)的行上得到一个空指针错误,因此连接器显然没有正确连接.

我试着创建一个构造和使用@Inject那里,但我通过手动添加这些模块new在我的应用程序引导类的列表,所以这有点出.

很显然,我失去了一些东西-我很可能只是new一个TokenConnector在这种情况下,因为它没有任何依赖关系本身,但不会解决我根本没有把握这里发生了什么.因此,如果您想查看(简化)其他代码片段或此代码的简化部分,请告诉我们.

Jef*_*ica 12

虽然你不能@Inject用于模块(除非你从另一个我强烈反对的注入器获得模块),你可以很容易地注入一个@Provides方法.

public class KeyHolderModule extends AbstractModule {
    private DateTime keyLastRefreshed;
    private String key;
    private Credentials creds = config.getCreds();

    @Override protected void configure() {}

    @Provides @Named("apiKey") public String getKey(
            TokenConnector connector) {
        // logic to check key last refreshed and handle generating a new one
        this.key = connector.getToken(creds);
        this.keyLastRefreshed = DateTime.now();

        return this.key;
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的技巧是模块通常在注入器创建时手动实例化,但是当需要它们提供的依赖关系时调用@Provides方法.因此,在构造Module时,Injector还没有准备好提供任何东西,但是在整个应用程序生命周期中调用的方法都可以访问它们可能需要的任何其他注入器提供的依赖项.当运行时,Injector尚未创建,您可以做的最好的就是调用(尽管在Injector准备好之前您无法调用它们).@ProvidesconfiguregetProviderget

我写了一些其他的模块内注入技术作为这个答案.