一、什么是Spring?
Spring是包含了众多工具方法的IoC容器。
二、什么是IoC?
Inversion of Control,就是“控制反转”的意思,是一种设计思想。
没有引入IoC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制。
而引入IoC的程序,将对象的创建交给第三方,也就是获得依赖对象的方式反转了。
IoC的设计思想,也实现了程序之间的解耦。
如图所示,因为有了IoC容器这个“第三方”,使得A、B、C、D这4个对象之间没有了耦合关系,齿轮之间的传动全部依靠“第三方了”,全部对象的控制权全部上交给“第三方”IoC容器,所以,IoC容器成了整个系统的关键核心,它起到了一种类似粘合剂的作用,把系统中所有对象粘合在一起发挥作用,如果没有这个粘合剂,对象与对象之间会彼此失去联系,这就是有人把IoC容器比喻成“粘合剂”的由来。
三、没有引入IoC的程序开发
现在来构建一个“车”的程序,实现思路是:
制造一辆车的流程:车依赖车身,车身依赖底盘,底盘又依赖轮胎。
所以实现如下:
package com.example.demo.ioc;
/**
* 传统的创建一辆“车”的流程
*/
public class NewCarExample {
public static void main(String[] args) {
Car car = new Car();
car.init();
}
/**
* 汽车对象
*/
static class Car {
public void init() {
// 依赖车身
Framework framework = new Framework();
framework.init();
}
}
/**
* 车身类
*/
static class Framework {
public void init() {
// 依赖底盘
Bottom bottom = new Bottom();
bottom.init();
}
}
/**
* 底盘类
*/
static class Bottom {
public void init() {
// 依赖轮胎
Tire tire = new Tire();
tire.init();
}
}
/**
* 轮胎类
*/
static class Tire {
// 尺寸
private int size = 30;
public void init() {
System.out.println("轮胎尺寸:" + size);
}
}
}
但是这时候我们发现,如果实现一个不同轮胎尺寸的车,我们就要修改这个制造车的代码:
package com.example.demo.ioc2;
/**
* 传统创建一辆车的流程(改进版)
*/
public class NewCarExample2 {
public static void main(String[] args) {
Car car=new Car();
car.init(50);
}
/**
* 汽车对象
*/
static class Car{
public void init(int size){
//依赖车身
FrameWork frameWork=new FrameWork();
frameWork.init(size);
}
}
/**
* 车身类
*/
static class FrameWork{
public void init(int size){
//依赖地盘
Bottom bottom=new Bottom();
bottom.init(size);
}
}
/**
* 底盘类
*/
static class Bottom{
public void init(int size){
//依赖轮胎
Tire tire=new Tire();
tire.init(size);
}
}
/**
* 轮胎类
*/
static class Tire{
public void init(int size){
System.out.println("轮胎尺寸:"+size);
}
}
}
四、引入IoC容器的程序开发
那么根据前面讲的IoC容器,我们可以知道,IoC容器可以实现对象之间的解耦,使获取依赖对象的方式反转,我们不再需要一个一个去new所需的对象,而是通过传入的方式。
package com.example.demo.ioc3;
import org.apache.catalina.core.FrameworkListener;
/**
* IoC实现的制造车
*/
public class IocCarExample {
public static void main(String[] args) {
Tire tire=new Tire(20);
Bottom bottom=new Bottom(tire);
FrameWork frameWork=new FrameWork(bottom);
Car car=new Car(frameWork);
car.run();
}
static class Car{
private FrameWork frameWork;
public Car(FrameWork frameWork){
this.frameWork=frameWork;
}
public void run(){
frameWork.init();
}
}
static class FrameWork{
private Bottom bottom;
public FrameWork(Bottom bottom){
this.bottom=bottom;
}
public void init(){
bottom.init();
}
}
static class Bottom{
private Tire tire;
public Bottom(Tire tire){
this.tire=tire;
}
public void init(){
tire.init();
}
}
static class Tire{
private int size;
public Tire(int size){
this.size=size;
}
public void init(){
System.out.println("轮胎尺寸:"+size);
}
}
}
这时对象之间的关系就变成了这样:
五、DI的概念
DI就是Dependency Injection的缩写,是“依赖注入”的意思。
所谓依赖注入就是由IoC容器在运行期间,动态地将某种依赖关系注入到对象之中。
所以IoC容器和DI就是从不同角度描述同一件事,是指通过引入IoC容器,利用依赖注入的方式,实现对象之间的解耦。
六、IoC容器和DI的关系
IoC容器是设计思想,有了思想是需要实现的,所以DI就是IoC的具体实现。
七、Sping IoC
Sping 是一个IoC容器,那么他是容器就具备两个功能:
- 将对象存入到容器
- 从容器中取出对象
将对象存放到容器中的好处就是将对象存储在IoC容器相当于将以后可能用到的所有工具制作好放在仓库中,需要的时候直接取就可以了,用完再把它放回仓库中。