第 2 章 Inject注入

使用Inject设置注入的方式。

2.1. field注入

Service.java与SerivceImpl.java不变,将Main.java改成如下形式。

import com.google.inject.*;

public class Main {
    @Inject
    private Service service;

    public static void main(String[] args) {
        Main main = Guice.createInjector().getInstance(Main.class);

        main.service.hello();
    }
}
        

这次我们让guice帮我们生成Main.class,Main.class中包含一个用@Inject注解的service字段,即便这个字段是private的,guice依然有办法把我们需要的ServiceImpl.class注入进去。下面调用一下main.service.hello()就明白了,如果guice没有动任何手脚main.service应该是null,可它现在可以正常运行,guice在生成Main.class的时候自动把@Inject注解的部分填充了我们需要的东西——ServiceImpl.class的实例。

把@Inject写在field上是代码最少的方式,相对的弱点是没办法进行单元测试。

例子:02-01。

2.2. constructor注入

import com.google.inject.*;

public class Main {
    private Service service;

    @Inject
    public Main(Service service) {
        this.service = service;
    }

    public static void main(String[] args) {
        Main main = Guice.createInjector().getInstance(Main.class);

        main.service.hello();
    }
}
        

这次把@Inject写在构造方法上,构造方法提供一个Service.class类型的参数,guice会调用这个构造方法进行依赖注入。

这种方法的好处是可以保证service只能在初始化的时候传入,不容易再通过其他途径修改其中的service,缺点是限制了构造方法的形式,必须用service做参数传入才可以创建实例。

例子:02-02。

2.3. setter注入

import com.google.inject.*;

public class Main {
    private Service service;

    @Inject
    public void setService(Service service) {
        this.service = service;
    }

    public static void main(String[] args) {
        Main main = Guice.createInjector().getInstance(Main.class);

        main.service.hello();
    }
}
        

setter注入是在对象构造之后才起作用,相对构造方法注入更灵活,但也要冒service不知在什么时候被修改的危险。

例子:02-03。

guice提供给我们三种注入方法,就是相信咱们可以在正确的地方选择正确的方法,现在看你的了。