IOC
对象之间的耦合性是无法避免的(类与类之间必然存在依赖性)
随着项目规模的增大,对象与对象之间的依赖关系越来越复杂。耦合度过高必然会出现牵一发而动全身。所以IOC理论就被提出来了
Spring通过IoC容器来管理所有Java对象(也称bean)及其相互之间的依赖关系
IOC(Inversion of Control)控制反转
在程序中引入“第三方”,也就是IOC容器,使得对象之间没有了耦合性,全部交给IOC处理
IOC的作用: 将对象之间的耦合性交给IOC处理
为什么叫控制反转?
当对象A运行需要对象B时,IOC容器会创建一个对象B注入到对象A需要的地方
没有IOC时,对象A是主动创建对象B的
有IOC时,对象A是被动接受IOC主动创建的对象B, 所以就叫控制反转:获得依赖对象的过程被反转了 (由IoC创建的对象B我们称为 bean)
依赖注入DI:比控制反转更合适的名字
从依赖注入的角度解释:在IOC容器运行时,将依赖关系注入到对象中
IOC的优缺点
优点:松耦合
缺点:IOC容器是通过反射(运行时动态生成对象)生成对象的,运行效率有一定的损耗
IOC框架有多种产品,引入一个全新的框架会增加学习和培训的成本
对于小项目,强调运行效率,或IOC框架产品不熟悉不建议贸然引用
IOC中最基本的技术就是“反射”编程,当然反射主要也是用来开发框架
反射的核心是 JVM 在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁
重点是运行时而不是编译时
IOC容器的一些产品
Sun ONE技术体系下的IOC容器有:轻量级的有Spring、Guice、Pico Container、Avalon、HiveMind;重量级的有EJB;不轻不重的有JBoss,Jdon等等。Spring框架作为Java开发中SSH(Struts、Spring、Hibernate)三剑客之一,大中小项目中都有使用,非常成熟,应用广泛,EJB在关键性的工业级项目中也被使用,比如某些电信业务。
.Net技术体系下的IOC容器有:Spring.Net、Castle等等。Spring.Net是从Java的Spring移植过来的IOC容器,Castle的IOC容器就是Windsor部分。它们均是轻量级的框架,比较成熟,其中Spring.Net已经被广泛应用于各种项目中。
私有封装依赖对象(bean)
那对象A怎么被动接受IOC主动创建的对象B,也就是IoC容器如何将对象B注入到对象A中呢-----通过 构造函数
public class Computer {
private String cpu; // CPU型号
private int ram; // RAM大小,单位GB
public Computer(String cpu, int ram) {
this.cpu = cpu;
this.ram = ram;
}
}
符合IoC的做法, Person 依赖Computer, 通过第三方IoC注入依赖对象
public class Person {
private Computer computer;
public Person(Computer computer) {
this.computer = computer;
}
}
不符合IoC
// 直接在Person里实例化Computer类
public class Person {
private Computer computer = new Computer(AMD, 3);
}
// 通过【非构造函数】传入依赖
public class Person {
private Computer computer;
public void init(Computer computer) {
this.computer = computer;
}
}
可以看出对象不会new, 而将new交给了 IoC
bean
bean是一个Java对象,根据bean规范编写出来的类,并由IoC容器生成的对象就是bean
IoC的应用有以下两种模式:
反射: 在运行状态中 , 根据提供的类的路径或类名, 通过反射来动态地获取该类的所有属性和方法
工厂模式: 把IoC容器当作一个工厂, 在配置文件或注解中给出定义, 然后利用反射技术 , 根据给出的类名生产相应的对象. 对象生成的代码及对象之间的依赖关系在配置文件中定义, 这样就实现了解耦.
org.springframework.beans和org.springframework.context包是SpringIoC容器的基础