Guice堆栈跟踪未完成



我记得从我用inject.getInstance(App.class)获得的对象开始,guide堆栈跟踪曾经是完整的

出于某种原因,堆栈跟踪现在停止在类似的提供者方法上

@Provides
public Interface buildRemoteClient() { }

所以我有

at ClientXXX
at XXXModule.buildRemoteClient()

那么它完成了吗?这很奇怪,因为我在TestModule中重写了这个方法。我看不出是谁被注入了这个,因为在调用这个方法之前,这个链早就应该被切断了。guide 4.0有什么变化吗?

更多详细

at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:466)
                    at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:155)
                    at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107)
                    at com.google.inject.Guice.createInjector(Guice.java:96)
                    at com.google.inject.Guice.createInjector(Guice.java:73)
                    at com.google.inject.Guice.createInjector(Guice.java:62)
                    at com.company.search.generalserver.GeneralServer.initialize(GeneralServer.java:166)

最后是这个(是的,这就是我觉得很奇怪的整件事)。。。

2) Could not find a suitable constructor in  com.company.finagle.thrift.ClientId. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.
                   at com.company.finagle.thrift.ClientId.class(ClientId.scala:7)
                   at com.company.search.hydrator.app.XXXXModule.buildRemoteClient(XXXXModule.java:37) (via modules: com.google.inject.util.Modules$OverrideModule -> com.google.inject.util.Modules$CombinedModule -> com.twitter.search.hydrator.app.XXXXModule)

好的,所以我添加了这个代码,它现在令人惊讶地工作,但从未停止在这个代码的断点。它根本不会执行这些代码。。。。

@Provides
@Singleton
private ClientId provideId() {
  return new ClientId("hydrator");
}

我不应该需要那个代码,因为我覆盖了它,它应该切断链条。。。这很奇怪,但我想它会检查每个依赖项,即使我处于测试模式,而且根本不需要ClientId。

堆栈跟踪并没有完全完成,因为Guice实际上并没有调用有问题的方法

在注入器创建时,Guice仍然会验证它可以自己发现的整个图。开发模式会影响单例创建,但不会影响注入器验证:不允许引用Guice永远无法提供的东西,否则Guice将面临更难调试的运行时异常的风险。

看起来Guice可以检测到对ClientId的需求,而ClientId没有(也可能不应该)@Inject注释的构造函数。即使它没有被调用,您也需要提供它,以便Guice可以声明其图是完整的。这就是为什么添加@Provides方法会有所帮助,即使它从未被调用过——您也可以使用它throw new RuntimeException()

尽管堆栈跟踪实际上并没有反映真实的调用,但它应该足够完整,可以让您识别Guice无法提供的依赖关系。我只能想象,经过编辑的ClientXXX通过@Inject注释的构造函数中的参数、@Inject注释的字段或buildRemoteClient()的参数请求ClientId(然后将其视为依赖项)。你知道@Inject构造函数或@Providers方法在哪里将ClientId作为参数吗?

(我不知道Modules.override是否应该让你不必提供一个完整的原始图,也不知道在Guice 4.0中这种行为是否发生了变化。也许另一个回答者会。)

最新更新