简体   繁体   English

Guice Inject Field中的字段不是由Guice创建的

[英]Guice Inject Field in class not created by Guice

I have a class like so, that I create myself somewhere in my code: 我有一个这样的类,我在我的代码中创建自己:

class StarryEyes {
   @Inject MyValidator validator;

   public StarryEyes(String name) {
      //..
   }

   public doSomething() {
      // validator is NULL
   }
}

I want Guice to inject an instance of validator, which has a @Singleton annotation. 我希望Guice注入一个验证器实例,它有一个@Singleton注释。 I have a module that's loaded at startup and it contains the line: 我有一个在启动时加载的模块,它包含以下行:

bind(MyValidator.class);

However, it doesn't seem to work as "validator" is always null. 但是,它似乎不起作用,因为“验证器”始终为空。 I've tried a number of variations like: 我试过了很多变化,比如:

bind(MyValidator.class)toInstance(new MyValidator());

or other things like that. 或其他类似的事情。 Is this not how Guice is supposed to work? 这不是Guice应该如何运作的吗?

Typically Guice needs to create objects to inject them. 通常Guice需要创建对象来注入它们。 If you just call new StarryEyes(name) , Guice isn't ever going to see that object so it won't be able to inject it. 如果您只是调用new StarryEyes(name) ,Guice将永远不会看到该对象,因此它无法注入它。 One thing you can do is to call injector.injectMembers(obj) on the object after you've created it. 您可以做的一件事是在创建对象后调用injector.injectMembers(obj) I wouldn't recommend that, though, as you should avoid referencing the injector in your code. 但是,我不建议您这样做,因为您应该避免在代码中引用注入器。

What you really probably want here is Assisted Inject . 你真正想要的是Assisted Inject With Assisted Inject, you'd declare the constructor for your class something like this: 使用Assisted Inject,您将为您的类声明构造函数,如下所示:

@Inject public StarryEyes(MyValidator validator, @Assisted String name)

What that means is that validator is a parameter that Guice should inject, while name must be "assisted" (that is, provided at the time the instance is created). 这意味着validator是Guice应该注入的参数,而name必须是“辅助的”(即,在创建实例时提供)。

You then create an interface like this: 然后,您创建一个这样的界面:

public interface StarryEyesFactory {
  StarryEyes create(String name);
}

With Assisted Inject, Guice can then implement that factory for you. 通过Assisted Inject,Guice可以为您实现该工厂。 You bind it like this: 你像这样绑定它:

bind(StarryEyesFactory.class).toProvider(
    FactoryProvider.newFactory(StarryEyesFactory.class, StarryEyes.class));

You then inject a StarryEyesFactory anywhere you want to create an instance of it. 然后,您可以在任何想要创建它的实例的地方注入StarryEyesFactory Where you would have called new StarryEyes(name) previously, you now call starryEyesFactory.create(name) instead. 如果您以前调用过new StarryEyes(name) ,现在调用starryEyesFactory.create(name) When you call create(name) on the factory, it will take the name and pass it to the constructor and provide the bound validator itself. 在工厂中调用create(name)时,它将获取名称并将其传递给构造函数并提供绑定的验证器本身。

Starting in Guice 3 , you do this using a FactoryModuleBuilder : 从Guice 3开始 ,您可以使用FactoryModuleBuilder执行此操作:

install(new FactoryModuleBuilder().build(StarryEyesFactory.class));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM