Spring
指的是 Spring Framework
(Spring
框架)
Spring
是一个包含了众多工具的IoC
容器。
IoC = Inversion of Control
翻译成中⽂是“控制反转”的意思,也就是说 Spring 是一个“控制反转”的容器。
构建⼀辆⻋(Car Class),然而车需要依赖⻋身(FrameWork Class),而车身需要依赖底盘(Bottom Class),而底盘需要依赖轮胎(Tire Class),最终程序的实现代码如下:
public class CarTest {
public static void main(String[] args) {
Car car = new Car();
//把车运行起来
car.run();
}
/**
* 车,依赖车身
*/
static class Car{
public void run(){
//依赖车身
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 = 15;
public void init(){
System.out.println("轮胎尺寸:" + size);
}
}
}
以上程序中,轮胎的尺寸是固定的15,然而随着对的车的需求量越来越大,个性化需求也会越来越多,这时候我们就需要加工多种尺寸的轮胎,那这个时候就要对上面的程序进行修改了,修改后的代码如下所示:
public class NewCarTest {
public static void main(String[] args) {
Car car = new Car();
//把车运行起来
car.run(15);
}
/**
* 车,依赖车身
*/
static class Car{
public void run(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{
// private int size = 15;
public void init(int size){
System.out.println("轮胎尺寸:" + size);
}
}
}
从以上代码可以看出,以上程序的问题是:当最底层代码改动之后,整个调用链上的所有代码都需要修改。
如何解决上述问题?
我们可以尝试不在每个类中自己创建下级类,如果自己创建下级类就会出现当下级类发生改变操作,自己也要跟着修改。此时,我们只需要将原来由自己创建的下级类,改为传递的方式(也就是注入的方式),因为我们不需要在当前类中创建下级类了,所以下级类即使发生变化(创建或减少参数),当前类本身也无需修改任何代码,这样就完成了程序的解耦。
基于以上思路,我们把调用汽车的程序示例改造⼀下,把创建子类的方式,改为注入传递的方式,具体实现代码如下:
public class IoCCarDemo {
public static void main(String[] args) {
Tire tire = new Tire(15,"白色");
Bottom bottom = new Bottom(tire);
FrameWork frameWork = new FrameWork(bottom);
Car car = new Car(frameWork);
car.init();
}
/**
* 汽车类
*/
static class Car {
private FrameWork frameWork;
public Car(FrameWork frameWork){
this.frameWork = frameWork;
}
public void init(){
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;
private String color;
public Tire(int size,String color){
//实现了尺寸的自定义
this.size = size;
this.color = color;
}
public void init(){
System.out.println("轮胎尺寸:"+size);
System.out.println("轮胎的颜色:"+color);
}
}
}
代码经过以上调整,无论底层类如何变化,整个调用链是不用做任何改变的,这样就完成了代码之间的解耦,从而实现了更加灵活、通用的程序设计了。
改进之后的控制权发生了反转,不再是上级对象创建并控制下级对象了,而是下级将对象注入到当前对象中,下级的控制权不再由上级类控制了,这样即使下级类发生任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC
的实现思想。
1.把对象存储到Spring中,
2.把对象从Spring中取出来。
Spring
是一个 IoC
容器,说的是对象的创建和销毁的权利都交给 Spring 来管理了,它本身又具备了存储对象和获取对象的能力。
DI 是 Dependency Injection
的缩写,翻译成中文是“依赖注入”的意思。
IoC
是控制反转,是一种设计思想;使用控制反转的思路,可以实现依赖类之间的解耦,在依赖类的底层发生变化的时候,无需关心它的实现和生命过程。
DI
是依赖注入,它是IoC
的一种实现手段,在程序运行的时候,动态的将对象注入当前类的一种实现机制。
所以,依赖注入(DI
)和控制反转(IoC
)是从不同的角度的描述的同一件事情,就是指通过引入IoC
容器,利用依赖关系注入的方式,实现对象之间的解耦。