本章内容
-
IoC Service Provider的职责
-
运筹帷幄的秘密——IoC Service Provider如何管理对象间的依赖关系
3.1 IoC Service Provider的职责
Ioc Service Provider 的职责相对来说比较简单,主要有两个:业务对象的构建管理和业务对象间的依赖绑定。
- 业务对象的构建管理。在Ioc 场景中,业务对象无需关心所依赖的对象如何构建如何取得,但这部分的工作始终要有人做。所以,Ioc Service Provider需要将对象的构建逻辑从客户端对象那里剥离出来,以免这部分的逻辑污染业务对象的实现
- 业务对象间的依赖绑定。对于Ioc Service Provider来说,这个职责是最艰巨也是最重要的,这是它最终使命所在。如果不能完成这个职责,那么,无论对象如何“呼唤”,也不会得到依赖对象的任何响应(最常见的倒是会收到一个NullPointerException)。IoC Service Provider通过结合之前构建和管理的所有业务对象,以及各个业务间可以识别的依赖关系,将这些对象的所依赖的对象注入绑定,从而保证每个业务对象在使用的时候,可以处于就绪状态。
3.2 运筹帷幄的秘密——IoC Service Provider如何管理对象间的依赖关系
3.2.1 直接编码方式
当前大部分的IoC容器都应该支持直接编码方式。在容器启动之前,我们可以通过程序编码的方式将被注入对象和依赖对象注册到容器中,并明确它们相互之间的依赖注入关系。
代码清单3-2 直接编码方式管理对象间的依赖关系
IoContainer container = ...;
container.register(FXNewsProvider.class,new FXNewsProvider());
container.register(IFXNewsListener.class,new DowJonesNewsListener());
...
FXNewsProvider newsProvider = (FXNewsProvider)container.get(FXNewsProvider.class);
newsProvider.getAndPersistNews();
代码清单3-3 直接编码方式管理基于接口注入的依赖注入关系
IoContainer container = ...;
container.register(FXNewsProvider.class,new FXNewsProvider());
container.register(IFXNewsListener.class,new DowJonesNewsListener());
...
container.bind(IFXNewsListenerCallable.class,comtainer.get(FXNewsProvider.class));
...
FXNewsProvider newsProvider = (FXNewsProvider)container.get(FXNewsProvider.class);
newsProvider.getAndPersistNews();
3.2.2 配置文件方式
这是一种较为普遍的依赖注入关系管理方式。想普通文本文件、properties文件、XML文件等,都可以成为关系依赖注入关系的载体。
代码清单3-4 通过Sping的配置方式来管理FXNewsProvider的依赖注入关系
<bean id="newsProvider" class="..FXNewsProvider">
<property name="newsListener">
<ref bean="djNewsListener"/>
</property>
<property name="newPersistener">
<ref bean="djNewsPersistener"/>
</property>
</bean>
<bean id="djNewsListener" class="..impl.DowJonesNewsListener"/>
<bean id="djNewsPersister" class="..impl.DowJonesNewsPersister"/>
代码清单3-5 从读取配置文件完成对象组装的容器中获取FXNewsProvider并使用
...
container.readConfigurationFiles(...);
FXNewsProvider newsProvider = (FXNewsProvider)container.getBean("newsProvider");
newsProvider.getAndPersistNews();
3.23元数据方式这种方式的代表实现是Google Guice
代码清单3-6 使用Guice的注解标注依赖关系后的FXNewsProvider定义
public class FXNewsProvider
{
private IFXNewsListener nwwsListener;
private IFXNewsPersister newsPersister;
@Inject
public FXNewsProvider(IFXNewsListener listener,IFXNewsPersister persister)
{
this.newsListener = listtener;
this.newsPersister = persister;
}
...
}
代码清单3-7 FXNewsProvider所使用的Module实现
public class NewsBindingModule extends AbstractModule
{
@override
protected void configure()
{
bind(IFXNewsListener.class).to(DowJonesNewsListener.class).in(Scopes.SINGLETON);
bind(IFXNewsPersister.class).to(DowJonesNewsListener.class).in(Scopes.SINGLETON)
}
}
代码清单3-8 从Guice获取并使用最终绑定完成的FXNewsProvider
Injector injector = Guice.createInjector(new NewsBindingModule());
FXNewsProvider newsProvider = injector.getInstance(FXNewsProvider.class);
newsProvider.getAndPersistNews();
注解最终也要通过代码处理来确定最终的注入关系,从这点儿来说,注解方式可以算作编码方式的一种特殊情况。
3.3 小结
本章就Ioc场景中的主要角色Ioc Service Provider给出了言简意赅的介绍。讨论了Ioc Service Provider的基本职责,以及它常用的几种依赖关系管理方式