2016-09-27 67 views
2

我有获取并保持一个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类中的列表中,所以这是有点。

显然我错过了这里的东西 - 我可能只是new上涨了TokenConnector在这种情况下,因为它本身没有任何依赖关系,但是这并不能解决我根本无法理解这里发生的事情。所以,如果你想看到(简化)其他代码段,或者简化了这段代码,请告诉我。

回答

6

尽管您不能使用@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方法当需要它们提供的依赖调用。因此,在构建模块时,注入器尚未准备好提供任何东西,但在整个应用生命周期中调用的方法都可以访问它们可能需要的任何其他注入器提供的依赖关系。当configure运行时,喷油器尚未创建,最好的方法是致电getProvider(尽管在喷油器准备就绪之前,您无法致电get)。

我写了各种其他模块内注入技术,如this SO answer

+0

或者我认为另一种方法是绑定一个key-provider,它可以注入并封装逻辑+返回键。这与使用@Provides的guice相同吗? – pandaadb

+1

@pandaadb我不知道你是否指任何我不熟悉的技术_key-provider_术语,但我肯定会认为这对模块来说有点沉重。如果这是我的代码审查,我当然会考虑将此提交给'提供者'顶级类,或随机提供的按键POJO(这可能是你的意思)。 –

+0

Cheers Jeff - 是的,我最终把这件事搬到了另一个班上(但是对我发现自己的情况很好奇,因为它似乎反映了我对guice的理解上的差距。 ,我会标记为已接受 –