Google Guice 依赖注入——对象究竟是在哪里创建的?

Google Guice Depedency Injection - Where exactly the object is created?

我有下面的代码,但我不明白新的 EmailService 实例是在哪里创建的。我试图检查许多其他 Whosebug 对话,但仍然无法清楚地了解它。

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");
    }
}

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

  1. 通过反射,Guice 分析了MyApplication 的构造函数,发现它依赖于MessageService (public MyApplication(MessageService service))。正是这个构造函数被采用,因为它被标记为 @Inject
  2. Guice 尝试找出此接口的绑定。在 AppInjector 中,您指定 MessageService 的实现是 EmailService (bind(MessageService.class).to(EmailService.class);)
  3. EmailService 通过 Java Reflection API. It is done via Class.newInstance
  4. 实例化
  5. 创建EmailService后,作为参数传递给MyApplication.class.newInstance()工厂。

备注:

  • 默认情况下,如果你没有指定任何额外的构造函数,有一个默认的没有参数的构造函数,这就是为什么EmailService没有依赖关系。
  • EmailService实例是一个单例,因为它被标记为@Singleton,所以如果会有更多的依赖它,将注入完全相同的实例
  • 如果你想创建binding to instance,你可以使用下面的代码:bind(MessageService.class).toInstance(new EmailService());
  • Google 图书馆在文档方面总是很丰富。我建议你通读这个 wiki:google/guice/wiki