目录
Spring对于学习java编程有及其重要的作用,有些人说没有Spring和它的框架,那么java作为编程语言就会失去半壁江山,甚至有些java程序员都说自己是Spring程序员,从这点足以看出Spring举足轻重的作用。
Spring是一个包含了众多工具并且可以对这些工具进行管理的Ioc容器 。
光看这个概念是很抽象的,为了真正的了解它,就需要认识Ioc和容器。首先容器我们都认识,不就是拿来装东西的器皿吗,然后我们需要用到它里面的东西时,再从容器中取出。在java中我们前面也认识了很多容器,集合就是一种容器,比如List、Map等,它们都是将数据结构存储在集合里面,当我们要用的时候,直接引用集合即可。容器的问题解决了,再来研究Ioc。
Ioc是英文Inversion Of Control的缩写,这句英文翻译成“控制反转”,在Spring中它是一种实现对象之间关系反转的一种思想。
因此Spring可以说是一个“控制反转”的容器 ,从“控制反转”字面上来理解Ioc是很抽象的,必须通过代码的形式来观察,下面通过一个案例演示来说明这种思想。
现在有一个需求:有一个客户需要买一辆车,因为现在的生产规模比较小,只能生产轮胎尺寸大小为50寸的车,恰好这个客户就需要这样的车。
那么我们现在就来实现一辆轮胎大小为50寸的整车:
- //现在需要轮胎尺寸大小为50寸的一辆整车
- //整车中包括:车、车身、底盘、轮胎,因此针对每一个对象都要单独创建一个类
- public class CreateCar {
- public static void main(String[] args) {
- Car car = new Car();
- car.init();
- }
-
- //汽车对象
- static class Car{
- public void init(){
- Farmework farmework = new Farmework();
- farmework.init();
- }
- }
-
- //车身对象
- static class Farmework{
- 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 = 50;
- public void init(){
- System.out.println("轮胎尺寸为:"+size);
- }
- }
- }
上面造的车就只有一种类型,但是我们作为企业不可能只做几个人的生意吧,我们希望的是能够满足大多数人的需求,比如有些人他要求轮胎尺寸60,车身颜色红色,底盘要求是碳纤维的,其他人要求车身颜色是白色......为了满足它们的需求如果按照上面的这种造车思路,代码就得向下面这样写:
- //现在需要轮胎尺寸大小为60寸的一辆整车
- //整车中包括:车、车身、底盘、轮胎,因此针对每一个对象都要单独创建一个类
- public class CreateCar2 {
- public static void main(String[] args) {
- Car car = new Car();
- car.init(60);
- }
-
- //汽车对象
- static class Car{
- public void init(int size){
- Farmework farmework = new Farmework();
- farmework.init(size);
- }
- }
-
- //车身对象
- static class Farmework{
- 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;
- public void init(int size){
- System.out.println("轮胎尺寸为:"+size);
- }
- }
- }
从上面的代码中就可以看出来,为了满足所有客户对轮胎尺寸的要求,我们就不得不将轮胎作为一个变量,让客户来决定,然后我们再对轮胎的尺寸做出修改。但是这一修改,所有对象的init方法都被修改了,从这点就暴露出这种代码思想的缺点。因为这个代码它的依赖关系是:
这种依赖关系,轮胎作为最底层一旦需求发生改变,那么在调用链上的所有方法都要受到影响 ,
这样的代码,它的耦合性很高,也就是代码之间的依赖关系很强。
而IoC——“控制反转”思想就对上面的这种依赖关系做出了调整:
来看一下调整之后的代码:
- //现在需要轮胎尺寸大小为60寸、轮胎颜色为红色的一辆整车
- //整车中包括:车、车身、底盘、轮胎,因此针对每一个对象都要单独创建一个类
- public class CreateCar {
- public static void main(String[] args) {
- Tire tire = new Tire(60,"红色");
- Bottom bottom = new Bottom(tire);
- Framework framework = new Framework(bottom);
- Car car = new Car(framework);
- car.init();
- }
-
- //汽车对象
- static class Car{
- //创建对象的方式二:间接创建———— 先申明,再利用构造函数创建public Car(Framework framework){this.framework = framework;}
- 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思想则是将每个类给独立开,函数之间的调用改为传递(注入)的方式,现在也不需要在每一个类中创建下一级类,所以下级类怎么改变,都不用修改任何代码,从而达到了程序的解耦。
再来说一说“控制反转”,这就好比一个工厂,他不可能什么汽车零配件都做,采用IoC思想就好像是把轮胎这个配件给外包出去了,工厂里面不需要在负责修改轮胎的参数,而是让外包来做,工厂只需要将客户的要求告诉给外包就行。但是这样也有风险,那就是外包如果做的产品质量很差,或者工期很长,那么就会影响到工厂的销售,所以主动权就不在工厂手里面了。而第一种方式是工厂自己在做,主动权在工厂手中,这种主动关系之间的转换就称为控制反转,这就是IoC最核心的思想。
IoC是用来控制反转的,使用控制反转的思想可以实现依赖类之间的解耦,可以让我们不在关心依赖类之间的具体实现以及它的生命过程,我们只需要在使用到具体类的时候,将这个类注入进来即可。
IoC的优点:
光有IoC思想还是不够,还得有具体的实现,这个具体的实现就是DI
DI是Dependency Injection的缩写,它意为依赖注入。依赖注入 就是在IoC容器运行期间,动态的将某种依赖关系注入到对象中。
就拿上面的代码举例:
上面圈起来的代码,在创建Car这个类的时候,动态的将Car这个类的依赖对象framework注入(注册)进来的过程就叫做DI(依赖注入)
Spring就是一个包含了众多工具Ioc容器,它的功能就是用来管理对象,负责对象的存入和取出。
IoC是一种思想,是用来控制反转的,使用控制反转的思想可以实现依赖类之间的解耦,可以让我们不在关心依赖类之间的具体实现以及它的生命过程,我们只需要在使用到具体类的时候,将这个类注入进来即可 。DI是控制反转实现的一种具体实现,当需要用到某个类的时候,它就动态的将这个类注入进去。它们两个的功能宏观没有区别,都是为了实现程序的解耦。