(1) Spring是什么?
我们常说的Spring的全称是: Spring Framework(Spring框架), 它是一个开源的框架, 有着活跃而且庞大的社区, 这就是它之所以能长久不衰的原因, Spring 支持广泛的应用场景, 他可以让java企业级的应用程序开发变得非常简单
用一句话概括就是, Spring是包含了众多工具方法的IOC容器
(2) 什么是IOC容器?
想到容器我们就可以和java的集合体系来做对比, 集合体系里面, 就拿list类来讲, list里面设置泛型之后就可以存放对应的数据, 相同的包括我们曾经使用的tomcat也是如此, tomcat是一个web应用程序的容器, 它负责将webApp发布到网络.
(3) 从传统开发认识spring
假如我们要构建一辆车的程序, 我们可以思考一下, 一辆车需要以下这几个部件:
- 车身(Framework)
- 底盘(Bottom)
- ......(中间还可以有很多部件,这里只列举几个即可)
- 轮胎(Tire)
上面的三个部件(车身, 底盘, 轮胎) 构成一辆车, 形成了下面的流程图:
从上图可以看出构建一辆车需要依赖于车身, 构建车身又要依赖于底盘, 相同的, 构建底盘也要依赖于轮胎, 这样层层依赖, 最终我们可以类比此过程来 简单用代码实现这个过程:
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); } } }
(4) 这种传统开发的缺陷
以上过程的轮胎尺寸是固定的, 然而随着对车的需求量的增大, 不同需求的轮胎尺寸孕育而生, 为了满足日益增长的个性化需求, 就需要加工多种不同的轮胎尺寸, 这个时候针对不同的尺寸就需要对上面的代码进行修改了:
public class NewCarUpdateExample { public static void main(String[] args) { Car car = new Car(20); car.run(); } /** * 汽⻋对象 */ static class Car { private Framework framework; public Car(int size) { framework = new Framework(size); } public void run() { // 依赖⻋身 framework.init(); } } /** * ⻋身类 */ static class Framework { private Bottom bottom; public Framework(int size) { bottom = new Bottom(size); } public void init() { // 依赖底盘 bottom.init(); } } /** * 底盘类 */ static class Bottom { private Tire tire; public Bottom(int size) { tire = new Tire(size); } 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); } } }
从(3)到(4) 的代码变换过程中可以看出: 当底层的业务逻辑改变之后, 相应的调用链上的代码全部都得修改.
(5)解决传统开发中的缺陷
如何解决上面的问题? 我们可以尝试不在每个l类中创建下级类, 如果创建下级类, 就会出现, 下级类发生改变操作的时候, 自己也要跟着修改.
此时, 我们只需要将原来由自己创建的下级类, 改为传递的方式, 因为我们不需要在当前类中创建下级类了, 此时即使下级类发生改变(增加或者减少函数的参数), 当前类本身也无序修改任何代码, 这样就完成了程序的解耦.
关于解耦: 耦合也就是各个模块之间的关联程度, 关联程度越高, 其耦合就越大, 他们之间相互的影响就越大, 解耦就是指解决代码的耦合性, 好的代码的耦合性是很低的, 也就是代码之间简单地实现了解耦.
解耦就好比我们要打造一辆完整的汽车, 如果所有的配件都是自己造的, 那么当客户需求发生改变的时候, 比如轮胎的尺寸不是原来自己造出来的尺寸了, 就需要重新修改尺寸, 如果我们把轮胎外包出去, 那么即使是轮胎尺寸发生改变, 我们只需要向代理厂商下订单就可以了, 我们自身不需要花费力气去修改轮胎尺寸.
基于上面的思想我们修改代码如下:
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); } } }
代码经过以上调整,⽆论底层类如何变化,整个调⽤链是不⽤做任何改变的,这样就完成了代码之间的解耦,从⽽实现了更加灵活、通⽤的程序设计了.
(6) 对比总结规律
- 在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire
- 改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car
我们发现了⼀个规:通⽤程序的实现代码,类的创建顺序是反的,传统代码是 Car 控制并创建了Framework,Framework 创建并创建了 Bottom,依次往下,⽽改进之后的控制权发⽣的反转,不再是上级对象创建并控制下级对象了,⽽是下级对象把注⼊将当前对象中,下级的控制权不再由上级类控制了,这样即使下级类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现思想.
(7) 理解IOC
回到我们的spring中, 我们刚开始就说过, Spring是包含了多个工具方法的IOC容器 , 这就是对spring的核心总结, 集成了多个工具方法的例子将会在后面的章节进行讲解, 那么我们下面来看看如何理解Spring是ioc容器这句话?
既然spring是一个ioc容器, 那么我们的重点应该还放在容器二字上面, 也就是他具备两个功能:
- 将对象存入到容器
- 从容器中取出对象
也就是说spring最核心的功能就是学习如何将一个对象存入到spring中去, 再从spring容器中取出的过程.
我们可以类比生产工具的时候, 将对象存储在ioc容器也就相当于将以后所有可能用到的工具全部制作好放到仓库中, 用的时候直接取就行了, 用完再把他放回仓库, 而new对象的操作就相当于每次使用的时候现做, 用完就扔了也不会保存, 下次用的时候还得重新去做, 这就是ioc容器和普通程序开发的区别.
Spring 是⼀个 IoC 容器,说的是对象的创建和销毁的权利都交给 Spring 来管理了,它本身⼜具备了存储对象和获取对象的能⼒.