摘《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的概念我仍然比较模糊,可能在实际运用中,套用上述的例子才能真正理解吧