Google Guice伪装注入-确切在哪里创建对象?

时间:2018-08-02 08:52:40

标签: java dependency-injection guice

我有以下代码,在这些代码中,我不了解在何处创建EmailService的新实例。我试图检查许多其他的stackoverflow对话,但仍然无法清楚地了解它。

public interface MessageService {
    void sendMessage(String msg, String recipient);
}

@Singleton
public class EmailService implements MessageService {

    @Override
    public void sendMessage(String msg, String recipient) {
        System.out.println("Sending Email to"+recipient+"Msg is:" + msg);
    }
}

public class MyApplication {
    private MessageService service;

    @Inject
    public MyApplication(MessageService service) {
      this.service = service;
    }

    public void sendMessage(String msg, String recipient) {
        this.service.sendMessage(msg, recipient);
    }
}

public class AppInjector extends AbstractModule {

    @Override
    protected void configure() {
      bind(MessageService.class).to(EmailService.class);
    }

}

public class ClientApplication {
    public static void main(String[] args) {
        Injector inj = Guice.createInjector(new AppInjector());
        MyApplication app = inj.getInstance(MyApplication.class);
        app.sendMessage("How are you?", "hello@hello.com");
    }
}

在此代码中的任何地方,都不会创建类似于(new EmailService())的类EmailService类的新实例。

1 个答案:

答案 0 :(得分:3)

  1. 通过反射Guice分析了MyApplication的构造函数,并发现它依赖于MessageServicepublic MyApplication(MessageService service))。之所以采用此构造函数,是因为它用@Inject
  2. 标记
  3. Guice试图找出此接口的绑定。在AppInjector中,您指定了MessageService的实现为EmailServicebind(MessageService.class).to(EmailService.class);
  4. EmailService通过Java Reflection API实例化。通过Class.newInstance
  5. 完成
  6. 创建EmailService后,将其作为参数传递给MyApplication.class.newInstance()工厂。

注意:

  • 默认情况下,如果您未指定任何其他构造函数,则存在一个默认的不带参数的构造函数,这就是EmailService不具有依赖项的原因。
  • EmailService实例是单例的,因为它被标记为@Singleton,因此,如果对它有更多依赖性,将注入完全相同的实例
  • 如果您想创建binding to instance,则可以使用以下代码:bind(MessageService.class).toInstance(new EmailService());
  • Google库中的文档总是很丰富。我建议您通读以下Wiki:google/guice/wiki