虽然业务对象可以通过 IoC 方式声明相应的依赖,但是最终最终仍然需要通过某种角色或者服务将这些相互依赖的对象绑定到一起,而 IoC Service Provider 就对应 IoC 场景中的这一角色。
3.1 IoC Service Provider 的职责
- 业务对象的构建管理:
IoC Service Provider
需要将对象的构建逻辑从客户端对象那里剥离出来,以免这部分逻辑污染业务对象的实现。 - 业务对象间的依赖绑定:
IoC Service Provider
通过结合之前构建和管理的所有业务对象,以及各个业务对象可以识别的依赖关系,将这些对象所依赖的对象注入绑定,从而保证每个业务对象在使用的时候,可以处于就绪状。
3.2 运筹帷幄的秘密——IoC Service Provider 如何管理对象间的依赖关系
3.2.1 直接编码方式
在容器启动之前,通过程序编码的方式将被注入的对象和依赖对象注册到容器中,并明确它们相互之间的依赖注入关系。
IoContainer container = new IoContainer<>();
container.register(FXNewsProvider.class, new FXNewsProvider());
container.register(IFXNewsListener.class, new DowJonesNewsListener());
FXNewsProvider newsProvider = (FXNewsProvider) container.get(FXNewsProvider.class);
newsProvider.getAndPersistNews();
通过为相应的类指定对应的具体实例,可以告知 IoC 容器,当我们要这种类型的对象实例时,请将容器中注册的、对应的那个具体实例返回给我们。
3.2.2 配置文件方式
<bean id="newsProvider" class="..FXNewsProvider">
<property name="newsListener">
<ref bean="djNewsListener"/>
</property>
<property name="newPersistener">
<ref bean="djNewsPersister"/>
</property>
</bean>
<bean id="djNewsListener" class="..impl.DowJonesNewsListener"></bean>
<bean id="djNewsPersister" class="..impl.DowJonesNewsPersister"></bean>
在容器启动之前,通过读取配置文件的方式将被注入的对象和依赖对象注册到容器中,并明确它们相互之间的依赖注入关系。
container.readConfigurationFiles(...);
FXNewsProvider newsProvider = (FXNewsProvider)container.getBean("newsProvider");
newsProvider.getAndPersistNews();
3.3.3 元数据方式
直接在类中使用元数据信息来标各个对象之间的依赖关系,然后由 Guice 框架根据这些注解所提供的信息将这些对象组装后,交给客户端对象使用。
public class FXNewsProvider {
private IFXNewsListener newsListener;
private IFXNewsPersister newPersistener;
@Inject
public FXNewsProvider(IFXNewsListener listener,IFXNewsPersister persister) {
this.newsListener = listener;
this.newPersistener = persister;
}
...
}
通过 @Inject,我们指明需要 IoC Service Provider 通过构造方法注入方式,为 FXNewsProvider 注入其所依赖的对象。
3.3 小结
略