Provider提供了依赖注入的另一种途径,在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。
修改后的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。