第 4 章 使用Provider

Provider提供了依赖注入的另一种途径,在Provider中我们可以定义自己的逻辑。

4.1. 使用Provider提供依赖

我们写一个ServiceProvider.class为Service.class提供依赖注入。

import com.google.inject.*;

public class ServiceProvider implements Provider<Service> {
    public Service get() {
        return new ServiceImpl();
    }
}
        

首先ServiceProvider要实现Provider接口,然后实现接口定义的方法T get(),还是jdk5的范型避免了强制转型,直接获得Service类型的对象,我们在get()方法中直接创建ServiceImpl.class对象,剩下的为了让ServiceProvider起作用,就要在Module里做设置了。

修改后的Main.java如下所示。

import com.google.inject.*;

public class Main {

    @Inject
    private Service service;

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

        main.service.hello();
    }
}
        

我们使用toProvider()把ServiceProvider.class绑定到Service.class上,在需要注入Service.class的地方就会调用ServiceProvider的get()方法获得Service实例再注入。

不过这样看起来,Provider也仅仅是一个工厂模式而已,为了让它更灵活,我们需要另一个注入方式。

例子:04-01。

4.2. 直接注入Provider

修改后的ServiceProvider.java如下。

import com.google.inject.*;

public class Main {

    @Inject
    private Provider<Service> serviceProvider;

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

        main.serviceProvider.get().hello();
    }
}
        

这里的关键在于我们向Main.class中注入了Provider<T>,guice自动帮咱们将ServiceProvider与Provider<T>绑定在一起,让我们可以直接使用。

下面我们需要使用service的时候,直接调用serviceProvider.get()就可以了。这给我们提供了巨大的便利,Main.class可以不必重新进行依赖注入就能通过serviceProvider获得最新的service实例,这就是它的神奇之处。

例子:04-02。