第 10 章 可选注入

Inject注解的一个参数,optional = true,它的默认值是false。

10.1. 找不到注入会抛异常

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

这段代码中,既没有用Module配置Service的注入关系,也没有使用@ImplementedBy注解,guice不知道该向@Inject属性注入什么,会直接抛出异常。

例子:10-01。

10.2. 使用optional=true

设置了optional=true之后,即使找不到注入的配置,也不会抛出异常。

import com.google.inject.*;

public class Main {

    @Inject(optional = true)
    private Service service = new OptionalImpl();

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

        main.service.hello();
    }
}
        

这样,找不到注入配置就会使用我们提供的new optionalImpl()实例,最后打印出来的是OptionalImpl中定义的optional。

例子:10-02。

10.3. 使用optional又能找到依赖

如果我们使用了optional = true,又在guice中定义了对于Service.class的依赖配置会出现什么结果呢?最后我们获得的是哪个实例呢?

import com.google.inject.*;

public class Main {

    @Inject(optional = true)
    private Service service = new OptionalImpl();

    public static void main(String[] args) {
        Main main = Guice.createInjector(new Module() {
            public void configure(Binder binder) {
                binder.bind(Service.class).to(ServiceImpl.class);
            }
        }).getInstance(Main.class);

        main.service.hello();
    }
}
        

这里,我们先用new OptionalImpl()设置缺少依赖配置时使用的默认值,然后在Module里配置ServiceImpl.class注入给Service.class。如果最终main.service.hello()显示optional说明获得的是OptionalImpl.class,如果显示hello说明获得的是ServiceImpl.class。

执行结果是

hello
        

说明在guice能知道依赖注入配置的时候,会覆盖我们定义的缺省值,这就可以保证数据的一致性,即使以前类里写了什么都可以使用Module里的配置进行覆盖。

例子:10-03。