摘《Spring高级程序设计》
Ioc 的类型
自己在刚开始学Spring的时候,就接触到两个词,Ioc(控制反转) 和 DI(依赖注入).
不知道什么时候形成了一个思维就是 Ioc就是DI,只是翻译不同. 我便将这两个概念混为一谈
然而,并非如此!!
Ioc的类型分为两类:
1,依赖查找
2,依赖注入
所以我们可以说DI是Ioc,但是Ioc并不是DI.
依赖查找和依赖注入又分为两类
依赖查找分为: dependency pull 和 contextualized depend-ency lookup
依赖注入分为: constructor DI 和 setter DI
那么它们的区别在哪里?书上给出了相应代码和UML做出解释,所以我希望列出这些例子可以直观的比较并加上自己的理解
dependency pull 例子:
public class DependencyPullDemo
{
public static void main(String[] args)
{
BeanFactory bf = getBeanFactory();
MessageService service = (MessageService) bf.getBean("service");
service.execute();
}
private static BeanFactory getBeanFactory()
{
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
BeanDefinitionReader reader = new PropertiesBeanDefinitionReader(bf);
reader.loadBeanDefinitions(new ClassPathResource(
"/META-INF/spring/ioc-pull-context.properties"));
return bf;
}
}
contextualized depend-ency lookup (CDL)例子:
public interface ManagedComponent
{
void lookup(BeanFactory container);
}
public class ContextualizedDependencyLookupDemo
{
private static Set<ManagedComponent> components = new HashSet<ManagedComponent>();
private static class MessageServiceComponent implements ManagedComponent
{
private MessageService service;
public void lookup(BeanFactory container)
{
this.service = (MessageService) container.getBean("service");
}
public void run()
{
this.service.execute();
}
}
public static void main(String[] args)
{
BeanFactory bf = getBeanFactory();
MessageServiceComponent msc = new MessageServiceComponent();
registerComponent(msc);
allowComponentsToLookup(bf);
msc.run();
}
private static void allowComponentsToLookup(BeanFactory bf)
{
for (ManagedComponent component : components)
{
component.lookup(bf);
}
}
private static void registerComponent(ManagedComponent managedComponent)
{
components.add(managedComponent);
}
private static BeanFactory getBeanFactory()
{
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
BeanDefinitionReader reader = new PropertiesBeanDefinitionReader(bf);
reader.loadBeanDefinitions(new ClassPathResource(
"/META-INF/spring/ioc-pull-context.properties"));
return bf;
}
}
可以看出两个例子都是从配置文件中读取信息,通过传入bean的名字对应配置文件来来获取bean的.
不同点书的作者有自己的说明,翻译过来就是"CDL是对 容器的 管理资源 进行 查找 " 而dependency pull是根据注册器查找,
例子中DefaultListableBeanFactory实现了许多注册器的接口,具体流程,我想看UML更为直观
----------------------------------------------------------------------------------------------------------------------------------------------------
constructor DI 例子:
public class CtorDependencyInjectionDemo
{
private static class DependentComponent
{
private MessageService service;
private DependentComponent(MessageService service)
{
Assert.notNull(service,
"The 'service' argument must not be null.");
this.service = service;
}
public void run()
{
this.service.execute();
}
}
}
setter DI例子:
public class SetterDependencyInjectionDemo
{
private static class DependentComponent
{
private MessageService service;
private DependentComponent()
{
}
public void setService(MessageService service)
{
this.service = service;
}
public void run()
{
this.service.execute();
}
}
public static void main(String[] args)
{
BeanFactory bf = getBeanFactory();
MessageService service = (MessageService) bf.getBean("service");
DependentComponent dc = new DependentComponent();
dc.setService(service);
dc.run();
}
private static BeanFactory getBeanFactory()
{ /* code as before */}
}
这样比较依赖查找和依赖注入就比较明显了,书上写了很多两者的比较
不过从前辈的总结里并不能深刻透彻的知道为什么
而这正是我缺少的,反而偏于比较的结果
现在对于Ioc的概念我仍然比较模糊,可能在实际运用中,套用上述的例子才能真正理解吧