将依赖项注入Guice模块

时间:2016-09-27 21:08:31

标签: java dependency-injection java-8 guice

我有一个获取并持有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;
    }
}

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

我尝试过创建一个构造函数并在那里使用@Inject,但是我通过new手动将这些模块添加到我的app bootstrap类中的列表中,以便进行排序出来

显然我在这里遗漏了一些东西 - 在这种情况下,我可能会new向上TokenConnector,因为它本身并没有任何依赖关系,但是这不会是&#39确定我根本无法掌握这里发生的事情。因此,如果您想查看(简化)其他代码段或此代码的简化部分,请告诉我们。

1 个答案:

答案 0 :(得分:11)

虽然您不能将@Inject用于模块(除非您从另一个我强烈反对的Injector获取模块),您可以轻松注入@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;
    }
}

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

我用this SO answer编写了各种其他模块内注入技术。