将依赖项注入 Guice 模块

Injecting a dependency into Guice Module

我有一个获取并持有 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 手动将这些模块添加到我的应用 bootstrap class 中的列表中,所以那有点过分了。

显然我在这里遗漏了一些东西——在这种情况下我可能只是 new 了一个 TokenConnector 因为它本身没有任何依赖关系,但这并不能解决我的问题根本无法理解这里发生的事情。因此,如果您想查看(简化的)其他代码片段,或这段代码的简化程度较低的片段,请告诉我。

虽然您不能将 @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;
    }
}

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

我将各种其他模块内注入技术写成 this SO answer