目录
前言
一、Spring是什么
二、Ioc容器
2.1、容器是什么
2.2、IoC容器又是什么
2.3、理解 Spring IoC
三、DI概念的说明
前言
本篇博客主要围绕Spring的基本概念来展开,包括如何理解Spring,以及IoC、DI是啥,区别是什么,Spring的核心功能。
一、Spring是什么
我们通常所说的 Spring 指的是Spring Framework(Spring 框架),它是⼀个开源框架,有着活跃⽽庞⼤的社区,这就是它之所以能⻓久不衰的原因。Spring ⽀持⼴泛的应⽤场景,它可以让 Java 企业级的应⽤程序开发起来更简单。
⽤⼀句话概括 Spring:Spring 是包含了众多⼯具⽅法的IoC 容器。
接下来的问题就是:什么是容器,什么是IoC容器?
二、Ioc容器
2.1、容器是什么
首先我们先来了解一下什么是容器:
容器是⽤来容纳某种物品的(基本)装置。 ——来⾃:百度百科
在我们的认知中,容器就是盛放物体的东西就是容器,其实在之前的学习中,我们就接触过容器了,java中的集合类,比如LIst/Map就是属于存储数据的容器,tomcat就是存放webapp的容器,容器的作用各有不同,但是只要是能存放东西的就是容器。
2.2、IoC容器又是什么
Spring本身其实就是一个容器,一个IoC容器,简言之,Spring就是IoC容器
IoC对应的英文是:Inversion of Control翻译成中⽂是“控制反转”的意思。那控制反转到底是反转什么呢?这就是一个值得思考的问题,其实,本质上就是将创建对象的权力进行反转。接下来我们就来解释一下具体是如何反转的,再通过代码来感受一下反转的过程。
我们都知道Java是一门面向对象的编程语言,在Java中一切皆对象,假如我们要使用一个类,就得自己通过new关键字来创建一个对象,这个时候创建对象的权力是掌握在我们自己手里的,而我们使用的Spring则是将创建对象的权力给反转了,将创建对象的事情交给Spring就可以了,不需要自己手动去创建了,这样的优势就在于能够降低代码的耦合度。
接下来就用一个例子来模拟一下IoC容器,感受一下传统的开发与使用Spring开发的区别(也就是控制反转与没反转的区别):
我们这里要举的例子是构建一辆车的例子,首先我们要构建一辆车,假设我们需要车身,底盘,车轮这几样东西,车子是需要依赖车身的,车身要依赖底盘,底盘又依赖轮胎。基于以上的描述,我们将用代码来演示一下传统开发(自己new对象)和使用IoC容器的区别;
我们主要需要创建以下四个类:Car、FramWork、Bottom、Tire。
代码解释:传统中我们是在Test类中new了一个Car类,Car类依赖FrameWork类,因此new了一个Framework对象,FrameWork又依赖Bottom类,因此FrameWork类中又new了一个Bottom对象,Bottom类中依赖Tire,因此new了一个Tire对象,各个类都执行了各自的init()方法,并且调用了依赖的类的init()方法,这样子各个类中就形成了一个依赖关系。
传统开发代码如下:
代码执行效果:
代码总结:以上代码是可以正确创建出一个Car对象的,但是,现在可以思考一个问题,就是当我们的车子的轮胎的大小是要定制的,大小要根据自己的需求来定制,因此,我们需要向Tire类中添加一个size变量,用于指定轮胎的尺寸。这时候其实对于这个代码来说,是非常麻烦的,是"牵一发而动全身的",看似只要在Tire类中加一个size变量,但是这个变量选哟我们传进去,我们需要在创建Tire对象的Bottom类中给Tire对象传参数,Bottom要给Tire对象传参数,参数又需要从创建Bottom的对象的FrameWork类中获取,依此类推,最后的参数就需要从Car里面来,这样子的话,我们所有的类的代码都要修改,总而言之,就是调用链上的代码全部都要做出修改,真可谓是牵一发而动全身。
如下所示:
模拟使用Spring进行开发:
以下为模拟的IoC容器的代码:(这里虽然还是new了对象,但是这是 IoC new的)
其他普通类都如下所示:
值得注意的是,我们呢没有在普通类中去手动的创建对象,而是直接将参数通过构造方法直接传过来了。直接使用了,代码执行的效果和传统的开发是一致的,但是,这里即使再需要增加参数,也不用再大费周章的去改那么多的代码了,这里就只是IoC容器的事情了,因此,这里主要要体现的就是我们创建对象的事情交给了IoC容器,需要对象直接取就可以了,具体如何取对象以及更多的问题会在后续的博客中介绍。
比较二者之间的区别以及使用IoC最大的优点:
创建顺序的不同:
在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire
改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car(代码中有体现)
我们发现了⼀个规律:通⽤程序的实现代码,类的创建顺序是反的,传统代码是 Car 控制并创建了 Framework,Framework 创建并创建了 Bottom,依次往下,⽽改进之后的控制权发⽣的反转,不再是上级对象创建并控制下级对象了,⽽是下级对象把注⼊将当前对象中,下级的控制权不再由上级类控制了,这样即使下级类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现思想。
从这里也很容易看出,IoC容器最大的优点就在于实现了解耦,降低了代码之间的耦合度,对象的创建和销毁的权利都交给了IoC容器,这也降低了程序猿开发的难度。
2.3、理解 Spring IoC
前面我们就提到过:Spring 是包含了多个⼯具⽅法的 IoC 容器;这句话的重点还是在容器和包含多个工具方法,至于包含多个工具方法这个后续再介绍,这里重点先来介绍一下容器;
在我们的日常生活中,也会有许许多多的容器,比如舀水的水瓢,就可以说是一个装水的容器,对于水瓢,我们关注的是什么?其实不过就是我们如何利用它装水,和如何用(取出)水瓢中的水。所以,对于水瓢这一装水的容器,我们就是关注它如何装水和取水。因此,对于我们的Spring IoC容器也是一样的道理,我们关注的主要就两件事,我们如何将对象存进IoC容器中,以及如何将对象从IoC容器中取出。
也就是说学 Spring 最核⼼的功能,就是学如何将对象存⼊到 Spring 中,再从 Spring 中获取对象的过程。
所以,总的来说Spring 就是⼀个 IoC 容器,说的是对象的创建和销毁的权利都交给 Spring 来管理了,它本身⼜具备了存储对象和获取对象的能⼒。
三、DI概念的说明
说到 IoC 不得不提的⼀个词就是“DI”,DI 是 Dependency Injection的缩写,翻译成中⽂是“依赖注⼊”的意思。
所谓依赖注⼊,就是由 IoC 容器在运⾏期间,动态地将某种依赖关系注⼊到对象之中。所以,依赖注⼊(DI)和控制反转(IoC)是从不同的⻆度的描述的同⼀件事情,就是指通过引⼊ IoC容器,利⽤依赖关系注⼊的⽅式,实现对象之间的解耦。
总的来说,IoC本质上就是一种思想,DI就是IoC思想的一种具体的实现。
在上面的模拟IoC容器的代码中,我们其实就用到了依赖注入的方式,体现在我们需要使用对象的时候,直接通过构造方法传入对象,这样子的方式就叫做依赖注入。