侧边栏壁纸
博主头像
快乐江湖的博客博主等级

更多内容请点击CSDN关注“快乐江湖”

  • 累计撰写 127 篇文章
  • 累计创建 33 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

第一章:Spring基本概念和核心思想

快乐江湖
2023-11-15 / 0 评论 / 0 点赞 / 8 阅读 / 22489 字

一:什么是Spring

Spring:是一个开源的Java框架,它提供了广泛的基础设施支持,用于构建Java应用程序。Spring框架的主要目标是简化Java应用程序的开发,提高代码的可维护性,并促进面向对象编程的最佳实践。总而言之,Spring是包含了众多工具方法的IoC容器

  • 容器 是用来容纳某种物品的基本装置
    • List/Map:数据存储容器
    • Tomcat:Web容器
  • IoC 是英文Inversion of Control的的缩写,中文含义为“控制反转”,也就是说Spring是一个控制反转的容器

二:理解Spring IoC

控制反转(IoC):是软件设计模式的一种,用于解决组件之间的依赖关系管理问题。在IoC模式中,控制权由应用程序代码转移到了一个容器或框架,它负责管理对象的创建、生命周期和依赖关系。这种反转控制的思想旨在降低组件之间的耦合度,提高代码的可维护性和可测试性。IoC核心思想包含用以下几个关键概念

  • 依赖关系反转(Dependency Inversion): 这是IoC的基础。它强调高层模块不应该依赖于底层模块,而两者都应该依赖于抽象。这意味着应用程序组件应该依赖于接口或抽象类,而不是具体的实现类。这有助于降低组件之间的紧耦合
  • 容器: IoC容器是一个负责管理对象的工厂,它负责创建、配置和维护应用程序中的各种对象。容器负责解析对象之间的依赖关系,并在需要时注入依赖
  • 配置: IoC容器通常使用外部配置文件(如XML文件或注解)来描述对象之间的依赖关系和配置信息。这使得可以在不修改应用程序代码的情况下,更改对象的配置和行为
  • 注入(Injection): IoC容器通过依赖注入将对象的依赖关系注入到对象中,而不是由对象自行创建或查找依赖。这有助于解耦和对象的创建和依赖解析过程

IoC的最常见实现之一是通过使用框架,如Spring框架,来实现依赖注入和控制反转。在Spring中,开发人员可以配置bean,并定义它们之间的依赖关系,然后Spring容器负责创建和管理这些bean,并自动注入它们的依赖关系。这大大简化了应用程序的开发和维护,提高了可扩展性和可测试性

为了能够更好的理解IoC,这里我们通过对比传统程序开发和IoC程序开发来进行说明

(1)传统程序开发

假设我们要构建一辆车(抽象类),这辆车非常简单,需要车身、底盘和轮胎三个部分,那么实现思路如下

具体来说

  • 想要一辆车得先要车身
  • 想要车身得先要底盘
  • 想要底盘得先要轮胎

实现代码如下

public class CreateCar {  
    public static void main(String[] args) {  
        Car car = new Car();  
        car.init();  
    }  
}

public class Car {  
    private Frame frame;  
  
    public Car() {  
        frame = new Frame();  
    }  
    public void init() {  
        // 车需要依赖车身  
        frame.init();  
        System.out.println("初始化车");  
  
    }  
}

public class Frame {  
    private Bottom bottom;  
  
    public Frame() {  
        bottom = new Bottom();  
    }  
  
    public void init() {  
        // 车身需要依赖底盘  
        bottom.init();  
        System.out.println("初始化车身");  
    }  
}

public class Bottom {  
    private Tire tire;  
  
    public Bottom() {  
        tire = new Tire();  
    }  
  
    public void init() {  
        // 底盘需要依赖轮胎  
        tire.init();  
        System.out.println("初始化底盘");  
    }  
}

public class Tire {  
    private int size = 20;  
  
    public void init (){  
        System.out.println("初始化轮胎");  
    }  
}

这种传统程序设计方法虽然符合人的逻辑思维,但是也存在着很大的弊端。主要体现在修改时极其不方便,牵一发而动全身,也就是耦合性太强。例如,如果需要对轮胎尺寸修改(或者对轮胎有更多的定制化需求,这里只是举了最简单的情形),就需要从最外面传入尺寸,所有代码都要修改

public class CreateCar {  
    public static void main(String[] args) {  
        int size = 100;  
        Car car = new Car(size);  
        car.init();  
    }  
}

public class Car {  
    private Frame frame;  
  
    public Car(int size) {  
        frame = new Frame(size);  
    }  
    public void init() {  
        // 车需要依赖车身  
        frame.init();  
        System.out.println("初始化车");  
  
    }  
}

public class Frame {  
    private Bottom bottom;  
  
    public Frame(int size) {  
        bottom = new Bottom(size);  
    }  
  
    public void init() {  
        // 车身需要依赖底盘  
        bottom.init();  
        System.out.println("初始化车身");  
    }  
}

public class Bottom {  
    private Tire tire;  
  
    public Bottom(int size) {  
        tire = new Tire(size); // 修改  
    }  
  
    public void init() {  
        // 底盘需要依赖轮胎  
        tire.init();  
        System.out.println("初始化底盘");  
    }  
}

public class Tire {  
    private int size = 20;  
  
    public Tire(int size) {  
        this.size = size; // 修改  
    }  
    public void init (){  
        System.out.println("初始化轮胎");  
    }  
}

(2)控制反转程序开发

可以发现,如果某个类创建了下级类,那么当下级类修改时自己也会受到影响。因此我们可以将这种创建的方式修改为注入,只是声明我需要这样的类,而不创建它。关于这个下级类的生命周期又它自己掌管,这样的话就完成了程序的解耦。如此一来,即使下级类发生变化,也不会影响上级类,因为我只是需要这样一个类,你只需要创建好给我即可

实现代码如下

public class CreateCar {  
    public static void main(String[] args) {  
        // 造轮胎  
        Tire tire = new Tire(15);  
        Bottom bottom = new Bottom(tire);  
        Frame frame = new Frame(bottom);  
        Car car = new ioc.Car(frame);  
        car.init();  
  
    }  
}

public class Car {  
    private Frame frame;  
    public Car(Frame frame) {  
        this.frame = frame;  
    }  
    public void init() {  
        // 依赖车身  
        frame.init();  
        System.out.println("初始化车身");  
    }  
}

public class Frame {  
    private Bottom bottom;  
  
    public Frame(Bottom bottom) {  
        this.bottom = bottom;  
    }  
    public void init() {  
        // 依赖底盘  
        bottom.init();  
        System.out.println("初始化底盘");  
    }  
}

public class Bottom {  
    private Tire tire;  
  
    public Bottom(Tire tire) {  
        // 传入一个Tire对象给Bottom  
        this.tire = tire;  
    }  
    public void init () {  
        // 依赖轮胎  
        tire.init();  
        System.out.println("初始化底盘");  
  
    }  
}

public class Tire {  
    private int size = 20;  
  
    public Tire(int size) {  
        this.size = size;  
    }  
    public void init() {  
        System.out.println("初始化轮胎 "  + "【size:" + size + "】");  
    }  
}

这样一来,对轮胎的任何定制化需求都只会在轮胎这个类中修改,上层所有轮均不会受到任何影响

public class CreateCar {  
    public static void main(String[] args) {  
        // 造轮胎  
        Tire tire = new Tire(15, "blue");  
        Bottom bottom = new Bottom(tire);  
        Frame frame = new Frame(bottom);  
        Car car = new ioc.Car(frame);  
        car.init();  
  
    }  
}

public class Car {  
    private Frame frame;  
    public Car(Frame frame) {  
        this.frame = frame;  
    }  
    public void init() {  
        // 依赖车身  
        frame.init();  
        System.out.println("初始化车身");  
    }  
}

public class Frame {  
    private Bottom bottom;  
  
    public Frame(Bottom bottom) {  
        this.bottom = bottom;  
    }  
    public void init() {  
        // 依赖底盘  
        bottom.init();  
        System.out.println("初始化底盘");  
    }  
}

public class Bottom {  
    private Tire tire;  
  
    public Bottom(Tire tire) {  
        // 传入一个Tire对象给Bottom  
        this.tire = tire;  
    }  
    public void init () {  
        // 依赖轮胎  
        tire.init();  
        System.out.println("初始化底盘");  
  
    }  
}

public class Tire {  
    private int size = 20;  
    private String color= "red";  
  
    public Tire(int size, String color) {  
        this.size = size;  
        this.color = color;  
    }  
    public void init() {  
        System.out.println("初始化轮胎 "  + "【size:" + size + ";color:" + color+ "】");  
    }  
}


对比这两种实现方式

  • 传统:类的创建顺序是反的,Car控制并创建了FrameFrame控制并创建了BottomBottom控制并创建了Tire
  • IoC:将控制权进行翻转,不再是上级对象创建并控制下级对象,而是下级对象注入到上级对象中,下级对象的生命周期又自己掌握

(3)理解Spring IoC

Spring是包含了多个工具方法的IoC容器

  • 容器:具备两个基本功能
    • 将对象存入容器
    • 从容器中取出对象
  • IoC:控制了对象的生命周期(创建、销毁)

你只需要学会如何将对象存入Spring,然后从Spring中获取对象即可。现在你不需要自己new对象了,全由Spring负责

(4)DI

依赖注入(DI):是指IoC容器在运行期间,动态地将某种依赖关系注入到对象之中。因此,DI和IoC描述的是同一件事情,只是角度不同——通过引入IoC容器,利用依赖关系注入的方式,实现对象解耦

0

评论区