From:http://jinnianshilongnian.iteye.com/blog/1471944

我对IoC/DI的理解

博客分类:

IoC

IoC Inversion of Control,控制反转, 控制权从应用程序转移到框架(如IoC容器),是框架共有特性
 
1、为什么需要IoC容器
1.1、应用程序主动控制对象的实例化及依赖装配 
  1. A a = new AImpl();
  2. B b = new BImpl();
  3. a.setB(b);

本质:创建对象,主动实例化,直接获取依赖,主动装配

缺点:更换实现需要重新编译源代码
           很难更换实现、难于测试

耦合实例生产者和实例消费者

 
  1. A a = AFactory.createA();
  2. B b = BFactory.createB();
  3. a.setB(b);
 
本质:创建对象,被动实例化,间接获取依赖,主动装配  (简单工厂) 
缺点:更换实现需要重新编译源代码
           很难更换实现、难于测试
 
 
  1. A a = Factory.create(“a”);
  2. B b = Factory.create(“b”);
  3. a.setB(b);
 
  <!—配置.properties-->
  1. a=AImpl
  2. b=BImpl
本质:创建对象,被动实例化,间接获取依赖, 主动装配
        (工厂+反射+properties配置文件、

Service Locator、注册表)

缺点:冗余的依赖装配逻辑
 
 
我想直接:
    //返回装配好的a
  1. A a = Factory.create(“a”);
 
              
1.2、可配置通用工厂:工厂主动控制,应用程序被动接受,控制权从应用程序转移到工厂
  1. //返回装配好的a
  2. A a = Factory.create(“a”);

<!—配置文件-->

  1. <bean id=“a” class=“AImpl”>
  2. <property name=“b” ref=“b”/>
  3. </bean>
  4. <bean id=“b” class=“BImpl”/>

本质:创建对象和装配对象,

          被动实例化,被动接受依赖,被动装配
        (工厂+反射+xml配置文件)
缺点:不通用
 
步骤:
1、读取配置文件根据配置文件通过反射
创建AImpl
2、发现A需要一个类型为B的属性b
3、到工厂中找名为b的对象,发现没有,读取
配置文件通过反射创建BImpl
4、将b对象装配到a对象的b属性上
【组件的配置与使用分离开(解耦、更改实现无需修改源代码、易于更好实现) 】
 
1.3、 IoC(控制反转)容器:容器主动控制
  1. //返回装配好的a
  2. A a = ApplicationContext.getBean(“a”);

<!—配置文件-->

  1. <bean id=“a” class=“AImpl”>
  2. <property name=“b” ref=“b”/>
  3. </bean>
  4. <bean id=“b” class=“BImpl”/>
本质:创建对象和装配对象、管理对象生命周期
          被动实例化,被动接受依赖,被动装配
        (工厂+反射+xml配置文件)
通用 

 
 
IoC容器:实现了IoC思想的容器就是IoC容器
 
2、IoC容器特点
1无需主动new对象;而是描述对象应该如何被创建即可
         IoC容器帮你创建,即被动实例化;
【2】不需要主动装配对象之间的依赖关系,而是描述需要哪个服务(组件),
        IoC容器会帮你装配(即负责将它们关联在一起),被动接受装配;
【3】主动变被动,好莱坞法则:别打电话给我们,我们会打给你;
【4】迪米特法则(最少知识原则):不知道依赖的具体实现,只知道需要提供某类服务的对象(面向抽象编程),松散耦合,一个对象应当对其他对象有尽可能少的了解,不和陌生人(实现)说话
【5】IoC是一种让服务消费者不直接依赖于服务提供者的组件设计方式,是一种减少类与类之间依赖的设计原则。
 
3、理解IoC容器问题关键:控制的哪些方面被反转了?
1、谁控制谁?为什么叫反转? ------ IoC容器控制,而以前是应用程序控制,所以叫反转 
2、控制什么?               ------ 控制应用程序所需要的资源(对象、文件……
3、为什么控制?             ------ 解耦组件之间的关系 
4、控制的哪些方面被反转了? ------ 程序的控制权发生了反转:从应用程序转移到了IoC容器。 
 
思考:
    1: IoC/DI等同于工厂吗?
    2: IoC/DI跟以前的方式有什么不一样?
领会:主从换位的思想
 
 
4、实现了IoC思想的容器就是轻量级容器吗
如果仅仅因为使用了控制反转就认为这些轻量级容器与众不同,就好象在说我的轿车与众不同因为它有四个轮子? 
 
容器:提供组件运行环境,管理组件声明周期(不管组件如何创建的以及组件之间关系如何装配的);
 
IoC容器不仅仅具有容器的功能,而且还具有一些其他特性---如依赖装配
             
控制反转概念太广泛,让人迷惑,后来Martin Fowler 提出依赖注入概念
Martin Fowler  Inversion of Control Containers and the Dependency Injection pattern  
http://martinfowler.com/articles/injection.html
 
 
DI
 
2、什么是DI
 
DI:依赖注入(Dependency Injection :用一个单独的对象(装配器)来装配对象之间的依赖关系 

 
2、理解DI问题关键
谁依赖于谁?           -------   应用程序依赖于IoC容器
为什么需要依赖?        -------   应用程序依赖于IoC容器装配类之间的关系
依赖什么东西?          -------   依赖了IoC容器的装配功能
谁注入于谁?            -------   IoC容器注入应用程序
注入什么东西?          -------   注入应用程序需要的资源(类之间的关系)

 

更能描述容器其特点的名字——“依赖注入”(Dependency Injection)
IoC容器应该具有依赖注入功能,因此也可以叫DI容器 
 
3、DI优点
    【1】帮你看清组件之间的依赖关系,只需要观察依赖注入的机制(setter/构造器),就可以掌握整个依赖(类与类之间的关系)。
    【2】组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中。
    【3】依赖注入的目标并非为软件系统带来更多的功能,而是为了提升组件重用的概率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不用关心具体的资源来自何处、由谁实现。
 
使用DI限制:组件和装配器(IoC容器)之间不会有依赖关系,因此组件无法从装配器那里获得更多服务,只能获得配置信息中所提供的那些。 
 
4、实现方式
   1、构造器注入
   2、setter注入
   3、接口注入:在接口中定义需要注入的信息,并通过接口完成注入
       @Autowired
       public void prepare(MovieCatalog movieCatalog,
           CustomerPreferenceDao customerPreferenceDao) {
           this.movieCatalog = movieCatalog;
           this.customerPreferenceDao = customerPreferenceDao;
       }
 
 
 
使用IoC/DI容器开发需要改变的思路
1、应用程序不主动创建对象,但要描述创建它们的方式。
2、在应用程序代码中不直接进行服务的装配,但要配置文件中描述哪一个组件需要哪一项服务。容器负责将这些装配在一起。
 
其原理是基于OO设计原则的The Hollywood Principle:Don‘t call us, we’ll call you(别找我,我会来找你的)。也就是说,所有的组件都是被动的(Passive),所有的组件初始化和装配都由容器负责。组件处在一个容器当中,由容器负责管理。
 
IoC容器功能:实例化、初始化组件、装配组件依赖关系、负责组件生命周期管理。
 
本质:
      IoC:控制权的转移,由应用程序转移到框架;
      IoC/DI容器:应用程序主动实例化对象被动等待对象(被动实例化);
      DI:  由专门的装配器装配组件之间的关系;
      IoC/DI容器:应用程序主动装配对象的依赖应用程序被动接受依赖
 

关于IoC/DI与DIP之间的关系 详见 http://www.iteye.com/topic/1122310?page=5#2335746

IoC/DI与迪米特法则 详见http://www.iteye.com/topic/1122310?page=5#2335748

IoC/DI的更多相关文章

  1. 关于依赖注入IOC/DI的感想

    之前一直不明白依赖注入有什么好处,甚至觉得它是鸡肋,现在想想,当时真是可笑. 这个想法正如同说接口是没有用处一样. 当整个项目非常庞大,各个方法之间的调用非常复杂,那么,可以想象一下,假设说没有任何的 ...

  2. Spring IOC/DI和AOP原理

    一 IOC/DI 1. 概念机原理 IOC: Inversion of Control(控制反转)是一种设计思想,就是容器控制应用程序所需要外部资源的创建和管理,然后将其反转给应用程序.对象及其依赖对 ...

  3. 深入理解IoC/DI

    ------------------------------------------------------------------------ 理解IoC/DI 1.控制反转 --> 谁控制谁 ...

  4. IoC/DI基本思想的演变

    ---------------------------------------------------------------------------------- (1)IoC/DI的概念 IoC ...

  5. 话说IOC(DI)

    什么是IOC(DI) 书上的东东,因为说的太严谨,所以不太容易懂,其实也没那么复杂. 举几个例子: 1.文明点的:中午太热,不想出去吃饭,所以希望同事能帮忙带饭,现在有了点外卖平台,我们就可以直接在网 ...

  6. 工厂方法模式与IoC/DI

    IoC——Inversion of Control  控制反转 DI——Dependency Injection   依赖注入 1:如何理解IoC/DI        要想理解上面两个概念,就必须搞清 ...

  7. spring 依赖注入(IOC DI)

    依赖注入(IOC DI) 依赖注入的两种方式: 1. set注入 Spring要求使用set注入方式的时候,Bean需要提供一个无参数的构造方法.并提供一个属性的setter方法.例如: packag ...

  8. spring--学习之IOC DI

    2.1.1  IoC是什么 Ioc-Inversion of Control,即"控制反转",不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器 ...

  9. spring ioc DI 理解

    下面是我从网上找来的一些大牛对spring ioc和DI的理解,希望也能让你对Spring ioc和DI的设计思想有更进一步的认识. 一.分享Iteye的开涛对Ioc的精彩讲解 Ioc—Inversi ...

  10. 工厂方法模式与IoC/DI控制反转和依赖注入

    IoC——Inversion of Control  控制反转 DI——Dependency Injection   依赖注入 要想理解上面两个概念,就必须搞清楚如下的问题: 参与者都有谁? 依赖:谁 ...

随机推荐

  1. php和java的一些比较

    现在市场上的电子商务软件基本上可归结为两大阵营,即PHP阵营和Java阵营.但对接触电子商务不久的用户来说,看到的往往只是它们的表相,只是明显的价格差异,却很难看出它们之间的实际差异.其实,PHP+ ...

  2. Material Design 设计--阴影的重要性

    <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_cont ...

  3. hdu 4691 Front compression

    暴力水过,剪一下枝= =果断是数据水了 #include<cstdio> #include<cstring> #include<algorithm> #define ...

  4. unicode string和ansi string的转换函数及获取程序运行路径的代码

    #pragma once#include <string> namespace stds { class tool { public: std::string ws2s(const std ...

  5. [反汇编练习] 160个CrackMe之018

    [反汇编练习] 160个CrackMe之018. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注 ...

  6. 在fmri研究中,cca的应用历史

    1.02年ola是第一个应用cca在fmri激活检测上的学者. <exploratory fmri analysis by autocorrelation maximization> 2. ...

  7. Java [Leetcode 144]Binary Tree Preorder Traversal

    题目描述: Given a binary tree, return the preorder traversal of its nodes' values. For example:Given bin ...

  8. Oracle 一次 锁表 处理小记

    同事说测试库上的一张表被锁了. 不能执行DML 操作. 锁表的准确说法应该是阻塞.之前的一遍blog里有说明: 锁 死锁 阻塞Latch 等待 详解 http://blog.csdn.net/tian ...

  9. Java单例模式和volatile关键字

    单例模式是最简单的设计模式,实现也非常"简单".一直以为我写没有问题,直到被 Coverity 打脸. 1. 暴露问题 前段时间,有段代码被 Coverity 警告了,简化一下代码 ...

  10. HTML5之video元素

    一.video元素支持的视频格式 HTML5中的video标签支持3种常用的视频格式: 1.Ogg = 带有Theora 视频编码和Vorbis 音频编码的 Ogg 文件: 2.MPEG4 = 带有H ...