当前位置: 首页 > news >正文

Spring基础及IoC容器的理解

Spring概念:

通常所说的Spring指的是Spring Framewprk(Spring框架),它是一个开源的框架。用一句话概括就是:Spring是包含了众多工具方法的IoC容器

什么是容器?

容器是用来容纳某种物品的装置,在之前的学习中,我们接触到的容器有List/Map(数据存储容器)Tomcat(Web容器)

什么是IoC容器?

Spring就是一个IoC容器,IoC(Inversion of Control)翻译成中文就是“控制反转”的意思,也就是说,Spring是一个“控制反转”的容器。

如何理解控制反转?

以前我们在一个类中使用另外一个类,需要New一个对象来使用,所以对象的生命周期是由当前代码或程序员来控制;控制反转其实是控制权反转,也就是说对象的生命周期,不由程序员或当前代码片段来控制,而是由Spring(Spring容器/IoC容器)来控制,这就叫做控制权反转。

为什么要使用IoC容器/Spring?

使用IoC容器最大的优点:可以实现解耦(松耦合)。
如何理解?我们可以想象成要造一辆车,要造这辆车得依赖于车身,车身又依赖于底盘,底盘依赖于轮胎。就像下面这张图所示:
在这里插入图片描述

下面我们用代码来演示这种关系:

传统的开发方式
  • 我们新建一个类,叫Car,这个类里面有一个init()方法,可以理解成造车的关键步骤,Car依赖于Framework类。
package old;public class Car {private  Framework framework;public  Car(){this.framework=new Framework();}public  void init(){System.out.println("执行了 Car  init方法");//依赖车身framework.init();}
}
  • 接着new一个Framework类,Framework依赖于Bottom。
package old;public class Framework {private  Bottom bottom;public  Framework(){this.bottom=new Bottom();}public  void  init(){System.out.println("执行了 Framework init 方法");//依赖底盘bottom.init();}
}
  • Framework又依赖于Bottom,于是我们再new一个Bottom类
package old;public class Bottom {private  Tire tire;public  Bottom(){this.tire=new Tire();}public  void init(){System.out.println("执行了 Bottom init 方法");//依赖轮胎tire.init();}
}
  • 最后new一个Tire类,定义属性size
package old;public class Tire {private  int size=20;public void init(){System.out.println("执行了Tire init 方法,Size:"+size);}
}
  • new一个Test类,测试一下代码是否正确:
package old;public class Test {public static void main(String[] args) {Car car=new Car();car.init();}
}

在这里插入图片描述
执行没有问题,上面的代码就是传统开发的过程。
但是如果对车的要求增加了,比如对于轮胎的size,不同的人群,对轮胎size大小要求不一样,在代码上体现就是不能再使用原来默认的size,我们Tire类中重载构造方法。

package old;public class Tire {private  int size=20;public  Tire(int size){this.size=size;}public void init(){System.out.println("执行了Tire init 方法,Size:"+size);}
}

但是这样会引发一系列的问题,Tire的构造方法是有参的,而Bottom又依赖于Tire,Bottom类也要随之改动,不然就会报错,就像下面这样:
在这里插入图片描述
我们先给Bottom补上需要的参数:

package old;public class Bottom {private  Tire tire;public  Bottom(int size){this.tire=new Tire(size);}public  void init(){System.out.println("执行了 Bottom init 方法");tire.init();}
}

Bottom中本身是没有参数size的,这里要改这个报错,需要传入size,于是这个size由Framework传入。Framework本身也没有size参数,于是需要Car传给它。

package old;public class Framework {private  Bottom bottom;public  Framework(int size){this.bottom=new Bottom(size);}public  void  init(){System.out.println("执行了 Framework init 方法");//依赖底盘bottom.init();}
}

当我们改完Framework类后,Car类也会出现问题,缺少size参数,我们重载Car的构造方法,进行有参构造传入size.

package old;public class Car {private  Framework framework;public  Car(int size){this.framework=new Framework(size);}public  void init(){System.out.println("执行了 Car  init方法");//依赖车身framework.init();}
}

然后我们在测试类中新建Car对象的时候设置size大小进行测试,我们把size设置成10:

package old;public class Test {public static void main(String[] args) {Car car=new Car(10);car.init();}
}

在这里插入图片描述
这样就可以随便设置轮胎size的大小,满足不同人群的需求。通过上面的代码可以可以看出,当我们最底层的代码发生改变时,整个调用链上的所有代码都需要改动,而且这只是改一个参数。那如果我们需要加别的参数并且做更改呢?这就非常麻烦,底层的代码改变,调用链上的所有代码都要跟着改变,这就是耦合———“牵一发而动全身”!
怎么解决这个问题呢?用IoC框架,使用IoC就可以实现解耦,就可以避免上面的问题。

IoC开发方式
  • 编写Car类,Car类依然依赖于Framework类,但是不同的是,我们使用Framework对象时不需要new了,直接声明一下,框架会给我们。
package ioc;
public class Car {private  Framework framework;public Car(Framework framework){this.framework=framework;}public  void  init(){System.out.println("Car init");framework.init();}
}
  • 编写Framework类,Framework依赖于Bottom,但是这里同样也没有new Bottom对象,同样是框架给我们的Bottom对象,直接去使用。
package ioc;public class Framework {private Bottom bottom;public Framework(Bottom bottom){this.bottom=bottom;}public  void  init(){System.out.println("Framework init");bottom.init();}
}
  • 编写Bottom类,Bottom依赖于Tire ,这里也没有new Tire对象,调用Tire时直接去框架中去取,然后给当前变量设置框架里面的bottom。
package ioc;public class Bottom {private  Tire tire;public  Bottom(Tire tire){this.tire=tire;}public  void  init(){System.out.println("Bottom init");tire.init();}
}
  • 编写Tire类,设置属性和init方法
package ioc;public class Tire {private   int size=15;public  Tire(){}public  void  init(){System.out.println("Tire init,size:"+size);}
}
  • 编写单元测试代码,这里是模拟Spring框架(不用关注这里的new对象),这是框架的事情。
package ioc;public class Test {private  Tire tire;private  Bottom bottom;private  Framework framework;private  Car car;public  Test(){this.tire=new Tire();this.bottom=new Bottom(this.tire);this.framework=new Framework(this.bottom);this.car=new Car(this.framework);}public static void main(String[] args) {Test test=new Test();test.car.init();}
}

在这里插入图片描述
然后我们给Tire设置size,将无参构造改成有参构造。

package ioc;public class Tire {private   int size=15;public  Tire(int size){this.size=size;}public  void  init(){System.out.println("Tire init,size:"+size);}
}

修改后整个调用链上的代码没有报错,调用链上的代码也不需要任何修改,Tire改动后哪里需要修改是Spring框架/IoC容器的事情,跟用户没有任何关系,Spring会自动去设置这些参数。
在这里插入图片描述
总结一下就是IoC帮我们实现了业务代码的解耦,实现了松耦合。不在是底层代码发生改变,整个调用链上的代码都要改变。这就是IoC的优点,实现解耦

http://www.lryc.cn/news/160514.html

相关文章:

  • 护网行动为什么给的钱那么多
  • 软考知识汇总-计算机系统
  • OpenCV 11(图像金字塔)
  • Linux学习笔记-Ubuntu系统用户、群组、权限管理
  • 文章预览 安防监控/视频存储/视频汇聚平台EasyCVR播放优化小tips
  • Nand Flash的特性及烧录问题
  • 【React 】useLayoutEffect 和 useEffect的区别
  • oracle数据库常见的优化步骤与脚本
  • 并发内存池(C++)
  • 本地起一个VUE 前端项目
  • Python爬虫:Selenium的介绍及简单示例
  • 每日刷题|回溯法解决全排列问题第二弹之解决字符串、字母大小排列问题
  • python循环遍历字典: title_content_list.append([key, value])print(ti
  • Redis List类型命令 - Set类型命令 - SortedSet类型命令
  • 等级保护 —— 安全控制点,安全要求
  • nginx-缓存
  • layui使用富文本已经使用第三方插件Kz.layedit来优化layui的富文本
  • 某公司二面面试题总结
  • Ubuntu编译运行socket.io
  • h5开发网站-页面内容不够高时,如何定位footer始终位于页面的最底部
  • 手机也可以搭建个人博客?安卓Termux+Hexo搭建属于你自己的博客网站【cpolar实现公网访问】
  • Support for password authentication was removed on August 13, 2021 解决方案
  • MPP 与 SMP 的区别,终于有人讲明白了【文末送书】
  • 华为OD机试真题【寻找最大价值的矿堆】
  • Java Maven 项目读取项目版本号
  • Lesson4-1:OpenCV图像特征提取与描述---角点特征
  • C++ 基础(一)题目练习
  • Webpack5入门到原理
  • 地形有通挂支隘险远六种情况
  • C++多态案例-设计计算器类