IoC,直观地讲,就是容器控制程序之间的关系,而非传统实现中,由程序代码直接操控。这也就是所谓“控制反转”的概念所在。控制权由应用代码中转到了外部容器,控制权的转移是所谓反转。IoC还有另外一个名字——“依赖注入(Dependency Injection)”。从名字上理解,所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,形象地说,即由容器动态地将某种依赖关系注入到组件之中。
下面通过一个生动形象的例子介绍控制反转。
比如,一个女孩希望找到合适的男朋友,如图6-2所示,可以有3种方式,即青梅竹马、亲友介绍、父母包办。

第1种方式是青梅竹马,如图6-3所示。

通过代码表示如下。
public class Girl {
  void kiss(){
    Boy boy = new Boy();
  }
}
第2种方式是亲友介绍,如图6-4所示。

通过代码表示如下。
public class Girl {
  void kiss(){
    Boy boy = BoyFactory.createBoy();
  }
}
第3种方式是父母包办,如图6-5所示。

通过代码表示如下。
public class Girl {
  void kiss(Boy boy){
    // kiss boy
   boy.kiss();
  }
}
哪一种为控制反转IoC呢?虽然在现实生活中我们都希望青梅竹马,但在Spring世界里,选择的却是父母包办,它就是控制反转,而这里具有控制力的父母,就是Spring所谓的容器概念。
典型的IoC可以如图6-6所示。

IoC的3种依赖注入类型如下。
第1种是通过接口注射,这种方式要求我们的类必须实现容器给定的一个接口,然后容器会利用这个接口给我们这个类注射它所依赖的类。
public class Girl implements Servicable {
  Kissable kissable;
  public void service(ServiceManager mgr) {
    kissable = (Kissable) mgr.lookup("kissable");
  }
  public void kissYourKissable() {
    kissable.kiss();
  }
}
<container>
  <component name="kissable" class="Boy">      
    <configuration> … </configuration>
  </component>
  <component name="girl" class="Girl" />
</container>
第2种是通过setter方法注射,这种方式也是Spring推荐的方式。
public class Girl {
  private Kissable kissable;
  public void setKissable(Kissable kissable) {
    this.kissable = kissable;
  }
  public void kissYourKissable() {
    kissable.kiss();
  }
}
<beans>
  <bean id="boy" class="Boy"/>
  <bean id="girl" class="Girl">
    <property name="kissable">
      <ref bean="boy"/>
    </property>
  </bean>
</beans>
第3种是通过构造方法注射类,这种方式Spring同样给予了实现,它和通过setter方式一样,都在类里无任何侵入性,但是,不是没有侵入性,只是把侵入性转移了,显然第1种方式要求实现特定的接口,侵入性非常强,不方便以后移植。
public class Girl {
  private Kissable kissable;
  public Girl(Kissable kissable) {
    this.kissable = kissable;
  }
  public void kissYourKissable() {
    kissable.kiss();
  }
}
PicoContainer container = new DefaultPicoContainer();
container.registerComponentImplementation(Boy.class);
container.registerComponentImplementation(Girl.class);
Girl girl = (Girl) container.getComponentInstance(Girl.class);
girl.kissYourKissable();

最新文章

  1. [Ajax系列]Ajax介绍
  2. mysql 同步
  3. C99标准的新特性
  4. Erlang 的新数据结构 map 浅析
  5. Lucene实践
  6. HDU 3887:Counting Offspring(DFS序+树状数组)
  7. 解决mysql登陆时出现“ERROR 2002 (HY000): Can&#39;t connect to local MySQL server through socket &#39;/var/run/mysql/mysql.sock&#39; (2)”
  8. 【转】第一次使用Android Studio时你应该知道的一切配置
  9. 洛谷1890 gcd区间
  10. 【CF39E】【博弈论】What Has Dirichlet Got to Do with That?
  11. 董的博客 hadoop
  12. 微信jssdk获取当前位置,以及打开微信地图
  13. SSE 系列内置函数中的 shuffle 函数
  14. mysql常用的提权方法
  15. XWork容器的存储结构
  16. Swap file &quot;.BranchModel.class.php.swp&quot; already exists!
  17. Android开发——使用Jword生成本地word文档
  18. UVA136 Ugly Numbers【set】【优先队列】
  19. 检测当前运行环境对es6的支持
  20. 20175317 《Java程序设计》第四周学习总结

热门文章

  1. 《Python核心编程》 第八章 条件和循环
  2. PHP 获取远程文件的大小的3种方法
  3. ORA-15041: diskgroup space exhausted
  4. bzoj 3439 Kpm的MC密码(Trie+dfs序+主席树)
  5. PLSQL 连接Oracle11g (64位)
  6. MAC机常用快捷键整理表格
  7. ffmpeg内置aac编码器正式发布
  8. ubuntu 备份安装程序列表
  9. RHEL安装配置JAVA
  10. 最新CentOS6.x下redis安装