• 初识Spring


    目录

    1.Spring 基础

    2.传统程序开发

    3.IoC程序开发(解耦)

    4.DI

    4.1 IoC 和 DI 有什么区别


    1.Spring 基础

    Spring 指的是 Spring Framework(Spring 框架),它是⼀个开源框架,有着活跃⽽庞⼤的社区,这就是它之所以能⻓久不衰的原因。Spring ⽀持⼴泛的应⽤场景,它可以让 Java 企业级的应⽤程序开发起来更简单。

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

    容器:⽤来容纳某种物品的(基本)装置(例如:List/Map --->  数据存储容器、Tomcat ----> Web 容器)

    IoC:IoC = Inversion of Control 翻译成中⽂是“控制反转”的意思,也就是说 Spring 是⼀个“控制反转”的容器

    控制(权)反转:对象的生命周期,不是由程序员(或当前代码片段)来控制,而是由 Spring(Spring 容器/ IoC容器)来控制

    IoC最大的优点:可以实现解耦(松耦合)

    2.传统程序开发

    假如,我们现在构建⼀辆“⻋”的程序,我们的实现思路是这样的:

    1. /**
    2. * 传统开发:汽车对象
    3. */
    4. public class Car {
    5. private Framework framework;//依赖车声,建立车身
    6. //在构造方法中 new
    7. public Car() {
    8. this.framework = new Framework();
    9. }
    10. public void init() {
    11. //依赖车身
    12. System.out.println("执行了 init 方法");
    13. framework.init();
    14. }
    15. }
    1. /**
    2. * 车身类
    3. */
    4. public class Framework {
    5. private Bottom bottom;
    6. public Framework() {
    7. this.bottom = new Bottom();
    8. }
    9. public void init() {
    10. //依赖底盘
    11. System.out.println("执行了 Framework init 方法");
    12. bottom.init();
    13. }
    14. }
    1. /**
    2. * 底盘类
    3. */
    4. public class Bottom {
    5. private Tire tire;
    6. public Bottom() {
    7. this.tire = new Tire();
    8. }
    9. public void init() {
    10. //依赖轮胎
    11. System.out.println("执行了 Bottom init 方法");
    12. tire.init();
    13. }
    14. }
    1. /**
    2. * 轮胎类
    3. */
    4. public class Tire {
    5. private int size = 15;
    6. public void init() {
    7. System.out.println("执行了 Tire init,Size:"+ size);
    8. }
    9. }

    这个时候我们执行这段代码:

    1. public class Test {
    2. public static void main(String[] args) {
    3. Car car = new Car();
    4. car.init();
    5. }
    6. }

    上述代码中轮胎的尺寸是固定的,然而随着对的车的需求量越来越⼤,个性化需求也会越来越多,这 时候我们就需要加工多种尺⼨的轮胎,那这个时候就要对上面的程序进行修改:

    注意每一类中size的改动

    1. /**
    2. * 传统开发:汽车对象
    3. */
    4. public class Car {
    5. private Framework framework;
    6. public Car(int size) {
    7. this.framework = new Framework(size);
    8. }
    9. public void init() {
    10. //依赖车身
    11. System.out.println("执行了 init 方法");
    12. framework.init();
    13. }
    14. }
    15. /**
    16. * 车身类
    17. */
    18. public class Framework {
    19. private Bottom bottom;
    20. public Framework(int size) {
    21. this.bottom = new Bottom(size);
    22. }
    23. public void init() {
    24. //以来底盘
    25. System.out.println("执行了 Framework init 方法");
    26. bottom.init();
    27. }
    28. }
    29. /**
    30. * 底盘类
    31. */
    32. public class Bottom {
    33. private Tire tire;
    34. //Botton 中没有size参数,继续让别人传参数
    35. public Bottom(int size) {
    36. this.tire = new Tire(size);
    37. }
    38. public void init() {
    39. //依赖轮胎
    40. System.out.println("执行了 Bottom init 方法");
    41. tire.init();
    42. }
    43. }
    44. /**
    45. * 轮胎类
    46. */
    47. public class Tire {
    48. private int size = 15;
    49. //传递 size 参数
    50. public Tire(int size) {
    51. this.size = size;
    52. }
    53. public void init() {
    54. System.out.println("执行了 Tire init,Size:"+ size);
    55. }
    56. }
    57. public class Test {
    58. public static void main(String[] args) {
    59. Car car = new Car(20);
    60. car.init();
    61. }
    62. }

    这个时候我们发现,虽然我们可以改变轮胎的尺寸,但是最底层代码改动之后,整个调用链上的所有代码都需要修改——耦合性问题

    需求指挥越来越多,改动的也会越来越多,这个时候我们就可以使用 IoC 进行解耦

    3.IoC程序开发(解耦)

    1. /**
    2. * IoC:汽车对象
    3. */
    4. public class Car {
    5. private Framework framework;
    6. //初始化(不是用传统开发):让框架传入(不管咋样传入),声明使用Framework
    7. //如果是一个IoC框架,运行代码,会拿到当前框架中的Framework 赋值到当前变量中就会有 framework
    8. public Car(Framework framework) {
    9. this.framework = framework;
    10. }
    11. public void init() {
    12. System.out.println("Car init");
    13. framework.init();
    14. }
    15. }
    16. public class Framework {
    17. private Bottom bottom;
    18. public Framework(Bottom bottom) {
    19. this.bottom = bottom;
    20. }
    21. public void init() {
    22. System.out.println("Framework init");
    23. bottom.init();
    24. }
    25. }
    26. public class Bottom {
    27. private Tire tire;
    28. public Bottom(Tire tire) {
    29. this.tire = tire;
    30. }
    31. public void init() {
    32. System.out.println("Bottom init");
    33. tire.init();
    34. }
    35. }
    36. public class Tire {
    37. private int size = 15;
    38. public Tire() {
    39. }
    40. public void init() {
    41. System.out.println("Tire init, Size:" + size);
    42. }
    43. }
    44. /**
    45. * 模拟 IoC 容器
    46. */
    47. public class Test {
    48. private Tire tire;
    49. private Bottom bottom;
    50. private Framework framework;
    51. private Car car;
    52. public Test() {
    53. this.tire = new Tire();
    54. this.bottom = new Bottom(this.tire);
    55. this.framework = new Framework(this.bottom);
    56. this.car = new Car(this.framework);
    57. }
    58. public static void main(String[] args) {
    59. Test test = new Test();
    60. test.car.init();
    61. }
    62. }

    需要改尺寸只需要修改 Tire 类中的尺寸:

    1. public class Tire {
    2. private int size = 15;
    3. public Tire(int size) {
    4. this.size = size;
    5. }
    6. public void init() {
    7. System.out.println("Tire init, Size:" + size);
    8. }
    9. }

    这个时候只需要改 IoC 容器(Spring 框架 )即可(IoC 与用户没有关系),Spring 框架会自动设置参数

    1. public class Test {
    2. private Tire tire;
    3. private Bottom bottom;
    4. private Framework framework;
    5. private Car car;
    6. public Test() {
    7. this.tire = new Tire(20);
    8. this.bottom = new Bottom(this.tire);
    9. this.framework = new Framework(this.bottom);
    10. this.car = new Car(this.framework);
    11. }
    12. public static void main(String[] args) {
    13. Test test = new Test();
    14. test.car.init();
    15. }
    16. }

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

    对比传统:

    通⽤程序的实现代码,类的创建顺序是反的,传统代码是 Car 控制并创建了Framework,Framework 创建并创建了 Bottom,依次往下,⽽改进之后的控制权发⽣的反转,不再是上级对象创建并控制下级对象了,⽽是下级对象把注⼊将当前对象中,下级的控制权不再由上级类控制了,这样即使下级类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现思想。

    既然 Spring 是⼀个 IoC(控制反转)容器,重点还在“容器”⼆字上,那么它就具备两个最基础的功能:

    • 将对象存入到容器
    • 从容器中取出对象

    也就是说学 Spring 最核心的功能,就是学如何将对象存入到 Spring 中,再从 Spring 中获取对象的过程

    将对象存放到容器中的好处:将对象存储在 IoC 容器相当于将以后可能⽤的所有共具制作好都放到仓库中,需要的时候直接取就行了,用完再把它放回到仓库。而new 对象的方式相当于,每次需要工具了,才现做,用完就扔掉了也不会保存,下次再⽤的时候还得重新做,这就是 IoC 容器和普通程序开发的区别

    4.DI

    DI 是 Dependency Injection 的缩写,翻译成中文是“依赖注入”的意思:指的是由 IoC 容器在运行期间,动态的将依赖对象获取到的过程

    1. public class Car {
    2. private Framework framework;
    3. public Car(Framework framework) {
    4. this.framework = framework;
    5. }
    6. public void init() {
    7. System.out.println("Car init");
    8. framework.init();
    9. }
    10. }

    在运行 Car 时,动态的将 Framework 拿到当前类中的过程就叫做 依赖注入 (在运行类的时候,需要有一个依赖类,依赖类就会从容器中动态的查询出来,赋值给变量,就可以直接使用这个方法)

    所以,依赖注⼊(DI)和控制反转(IoC)是从不同的⻆度的描述的同⼀件事情,就是指通过引⼊ IoC 容器,利⽤依赖关系注⼊的⽅式,实现对象之间的解耦;

    IoC 是“目标”也是⼀种思想,而目标和思想只是⼀种指导原则,最终还是要有可行的落地方案,而 DI 就属于具体的实现

    如说我今天吃⼀顿美餐,那么“美餐”是目标(是 IoC),但最后我是吃火锅还是烧烤?这就是具体的实现,就是DI

    4.1 IoC 和 DI 有什么区别

    IoC 和 DI 都是 Spring 框架中的核心概念,它们的区别在于:

    • IoC(Inverse of Control,控制反转):它是一种思想,主要解决程序设计中的对象依赖关系管理问题。在 IoC 思想中,对象的创建权反转给第三方容器,由容器进行对象的创建及依赖关系的管理。
    • DI(Dependency Injection,依赖注入):它是 IoC 思想的具体实现方式之一,用于实现 IoC。在 Spring 中,依赖注入是指:在对象创建时,由容器自动将依赖对象注入到需要依赖的对象中。

    简单来说,它们的关系是:

    • IoC 是一种思想、理念,定义了对象创建和依赖关系处理的方式。
    • DI 是 IoC 思想的具体实现方式之一,实际提供对象依赖关系的注入功能。

    所以 IoC 是更基础和广义的概念,DI 可以说是 IoC 的一种实现手段。大多数情况下,我们提到 IoC 的时候,其实意味着 DI,因为 DI 已经是 IoC 最常见和广泛使用的实现方式了。

    例如在 Spring 框架中:

    • IoC 体现为 Spring 容器承担了对象创建及依赖关系管理的控制权。
    • DI 体现为 Spring 容器通过构造方法注入、Setter 方法注入等方式,将依赖对象注入到需要依赖的对象中。

    所以综上,IoC 和 DI 之间的关系可以这样理解:

    • IoC 是理论,DI 是实践。
    • IoC 是思想,DI 是手段。
    • IoC 是整体,DI 是部分。
  • 相关阅读:
    Spark Streaming 基本操作
    yolov5 obb旋转框 tensorrt部署
    TVM神经编译器
    OpenCV3-Python(7)模板匹配和霍夫检测
    求一个网页设计作业——个人博客(HTML+CSS)
    CentOS7.9安装jdk1.8
    开源协作开发者内容平台Vrite
    3D人体建模的前沿探索:细数主流模型与技术进展
    Golang字符串类型原理及其使用方法
    标准应用 | 数据库防火墙安全技术解析与实践
  • 原文地址:https://blog.csdn.net/m0_72161237/article/details/133682179