• Spring——如何理解Spring,DI和IoC


    1. Spring 是什么

    用一句话概括:Spring 是包含了众多工具方法的 IoC 容器

    2. 什么是容器

    容器顾名思义是 用来容纳某种物品的装置
    列如:
    Spring - > IoC 容器
    List / Map - > 数据存储容器
    Tomcat - > Web 容器

    3. 什么是 IoC

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

    如何理解这句话呢?我们来看个例子:

    假如,我们现在构建一辆 “车” 的程序,我们的实现思路是这样子的:
    在这里插入图片描述
    构建⼀辆⻋(Car Class),然⽽⻋需要依赖⻋身(FrameWork Class),⽽⻋身需要依赖底盘(BottomClass),⽽底盘需要依赖轮胎(Tire Class),我们在 车对象 里面需要 new 一个 车身 ,车身对象 里面需要 new 一个 底盘,底盘对象 里面需要 new 一个 轮胎 最终程序的实现代码如下:

    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);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    但是当我需要修改底层的代码的时候(如增加车身颜色时),上面的每一个类都需要改变,量很大,并且很麻烦!如下,每个类都需要增加 String Color,传入变量也需要增加:

    public class NewCarExample2 {
        public static void main(String[] args) {
            NewCarExample2.Car car = new NewCarExample2.Car();
            car.init(50,"粉色");
        }
     
        /**
         * 汽车对象
         */
        static class Car {
            public void init(int size,String color) {
                // 依赖车身
                NewCarExample2.Framework framework = new NewCarExample2.Framework();
                framework.init(size,color);
            }
        }
     
        /**
         * 车身类
         */
        static class Framework {
            public void init(int size,String color) {
                // 依赖底盘
                NewCarExample2.Bottom bottom = new NewCarExample2.Bottom();
                bottom.init(size,color);
            }
        }
     
        /**
         * 底盘类
         */
        static class Bottom {
     
            public void init(int size,String color) {
                // 依赖轮胎
                NewCarExample2.Tire tire = new NewCarExample2.Tire();
                tire.init(size,color);
            }
        }
        static class Tire {
            // 尺寸
     
            public void init(int size,String color) {
                System.out.println("轮胎尺寸:" + size + "| 车身颜色: " + color );
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    基于以上思路,我们把调⽤汽⻋的程序示例改造⼀下,把创建⼦类的⽅式,改为注⼊传递的⽅式,具体实现代码如下:

     
    public class IocCarExample {
        public static void main(String[] args) {
            Tire tire = new Tire(40, "红色");
            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;
     
            private String color;
     
            public Tire(int size, String color) {
                this.size = size;
                this.color = color;
            }
     
            public void init() {
                System.out.println("轮胎:" + size + " | 颜色:" + color);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    改进之后的控制权发生的控制权发生的反转,又下级对象把注入当前对象中,下级的控制权不在由上级类控制,这样即使下级类发生任何改变,当前类都是不受影响,这就是典型的控制反转,也就是IoCde 实现思想。

    代码经过以上调整,⽆论底层类如何变化,整个调⽤链是不⽤做任何改变的,这样就完成了代码之间的解耦,从⽽实现了更加灵活、通⽤的程序设计了

    对比总结规律

    在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire
    改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car

    4. Spring IoC 容器的最核心功能

    1. 将 Bean(对象) 存储到 Spring(容器)中
    2. 将 Bean(对象) 从 Spring(容器)中取出来

    5. DI概念说明

    DI 是 Dependency Injection 的缩写,翻译成中⽂是“依赖注⼊”的意思。

    所谓依赖注入,就是由 IoC 容器在运行期间,动态的将某种依赖关系注入到对象当中

    可以这样理解 DI 和 IoC 是从不同角度去描述一件事情,IoC是一种思想,而 DI 则是一种实现

  • 相关阅读:
    最小生成树
    python中统计计数的几种方法+ 统计label个数
    JDK 下载 安装 配置环境变量
    RT-Thread实战笔记-小白一看就会的平衡车教程(附源码)
    我用PYQT5做的第一个实用的上位机项目(三)
    【bash工具】jq遍历list
    问题记录与思考
    [SSR渲染学习]nuxt的跨域处理
    探索深度学习:PyTorch与Transformer的区别与联系
    软考高级-系统架构师-软件架构设计练习题
  • 原文地址:https://blog.csdn.net/Biteht/article/details/127853357