IOC(Inversion of Control)
背景
在以往的面向对象的程序中,复杂的业务逻辑都是通过对象之间的彼此通信合作来完成的,如下图所示:
在上图中,对象A,B,C,D,E之间,存在着复杂的依赖关系,当其中一个对象出现问题时,就会导致其他的对象无法继续工作。为了解决对象之间耦合度过高,相互之间依赖太强的问题,Michael Mattson提出了IOC的概念。
IOC(控制反转)和DI(注入依赖)
什么是IOC
IOC的全称是Inversion of Control,中文为“控制反转”。下面我们通过一张图来解释
在第一张图中,五个对象要完成相互协作,都是采用new关键字来实现,这种方式存在的问题在上一部分已经讲解过,再次就不再赘述。IOC的思想就是借助于“第三方”来实现对象之间的解耦。
在上图中,IOC容器就承担着这样的“第三方”的职责,IOC容器的引入,使得A,B,C,D,E这五个对象之间没有耦合关系,试想上图中IOC容器不存在时,这五个对象便是五个独立的整体,相互之间没有约束,每个对象的实现都只需考虑自身内部的逻辑规则。那么他们是如何协作的呢?处于核心位置的IOC核心容器便完成了这一工作,每个对象的控制权都掌握在IOC容器中,例如创建和销毁的权利等。例如在第一张图中,C对象要完成自身的职责需要B和E对象的支持,那么在C对象执行到需要B和E的地方时,IOC容器会自动创建一个B和E对象注入到C对象相应的位置中,这也正是解释了“控制反转”这一名称的来源。在IOC容器引入之前,C对象对B和E对象有依赖关系时,C对象会主动的去创建B和E对象,在IOC引入之后,就改变了这总局面,C对象得到B和E对象的支持方式由主动变成了被动,这便是“控制反转”。
什么是DI
IOC和DI其实是同一事物的不同表现,IOC强调的是对象的管理,DI则强调是将一个对象注入到需要的位置。例如在C对象中,需要B和E对象,Spring会在合适的时机将对象注入在C对象的合适的位置中。在Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。
基于XMl的IOC配置
创建对象
AccountService.java
public class AccountService {
public AccountService(){
System.out.println("对象创建了");
}
public void take() {
System.out.println("service中的take方法执行的");
}
public void init(){
System.out.println("对象初始化了");
}
public void destroy(){
System.out.println("对象销毁了");
}
}
配置xml
bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--把对象的创建交给spring来管理-->
<!--id:对象的名称,即唯一标识
class:对象所对应的类,这里填写全限定类名,spring将根据全限定类名在进行加载-->
<bean id="accountService" class