Spring核心思想篇【持续更新】

1. 概念篇

1.1 IoC是什么?

Spring是一个包含了各种工具的IoC容器

将对象存储的在容器中用的时候直接取,用完之后再放回【单例模式】
new对象就相当于每次需要用的时候现做,用完之后就扔掉,下次使用需要重新制作

Inversion of Control「控制反转」也就是说 Spring 是一个控制反转的容器

以前我们操作对象需要 new 对象,由对象的作用域决定生命周期。使用 Spring 之后,就由框架提供了统一的容器来管理,实例化这些对象,并自动组织对象的之间的复杂依赖关系「体现在代码中就是对象中成员变量引入另一个变量」

为何叫控制反转

从使用上看,之前的 new 对象、设置属性这些控制权限都在使用者身上;使用了 Spring容器 之后,现在全部转移到容器中,容器会自动管理组织这些对象之间的关系依赖。因为控制权限发生了反转,所以叫控制反转

该如何理解呢?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZQDn9XQ0-1651373641275)(/Users/cxf/Desktop/MarkDown/images/传统开发.png)]

这个是传统的一辆汽车生产过程

代码实现如下

package old;

/**
 * 轮胎
 */
public class Tire {
    private int tireSize;

    public void init(int tireSize) {
        this.tireSize = tireSize;
        System.out.println("Tire size:" + this.tireSize);
    }
}

package old;

/**
 * 底盘
 */
public class Bottom {
    private Tire tire;

    public Bottom() {
        this.tire = new Tire();
    }

    public void init(int tireSize) {
        tire.init(tireSize);
        System.out.println("Bottom init.");
    }
}

package old;

/**
 * 车身
 */
public class Framework {
    private Bottom bottom;

    public Framework() {
        this.bottom = new Bottom();
    }

    public void init(int tireSize) {
        bottom.init(tireSize);
        System.out.println("Framework init.");
    }
}

package old;

public class Car {
    private void init(int tireSize) {
        Framework framework = new Framework();
        framework.init(tireSize);
    }

    public static void main(String[] args) {
        int tireSize = 19;
        Car car = new Car();
        car.init(tireSize);
    }
}

//运行结果
Tire size:19
Bottom init.
Framework init.

弊端:如果想修改轮胎的花纹,刹车钳,轮毂。。。 那么就需要从 Tire 底层开始修改。由于 Bottom 依赖 TireFramework 依赖 Bottom。所以会导致整个供应链上的修改【耦合太高】

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lelK9bNe-1651373641277)(/Users/cxf/Desktop/MarkDown/images/IOC.png)]

package v2;

public class TireV2 {
    private int tireSize;
    private String tireTread;

    public TireV2(int tireSize, String tireTread) {
        this.tireSize = tireSize;
        this.tireTread = tireTread;
    }

    public void init() {
        System.out.println("Tire size:" + tireSize);
        System.out.println("Tire tread:" + tireTread);
    }
}

package v2;

public class BottomV2 {
    private TireV2 tireV2;

    public BottomV2(TireV2 tireV2) {
        this.tireV2 = tireV2;
    }

    public void init(){
        tireV2.init();
        System.out.println("BottomV2 init");
    }
}

package v2;

public class FrameworkV2 {
    private BottomV2 bottomV2;

    public FrameworkV2(BottomV2 bottomV2) {
        this.bottomV2 = bottomV2;
    }

    public void init(){
        bottomV2.init();
        System.out.println("FrameworkV2 init.");
    }
}

package v2;

public class CarV2 {
    private FrameworkV2 frameworkV2;

    public CarV2(FrameworkV2 frameworkV2) {
        this.frameworkV2 = frameworkV2;
    }

    public void init(){
        frameworkV2.init();
        System.out.println("CarV2 init.");
    }
}

package v2;

public class App {
    public static void main(String[] args) {
        int tireSize = 17;
        String tireTread = "All-Season Tread";
        TireV2 tireV2 = new TireV2(tireSize, tireTread);
        BottomV2 bottomV2 = new BottomV2(tireV2);
        FrameworkV2 frameworkV2 = new FrameworkV2(bottomV2);
        CarV2 carV2 = new CarV2(frameworkV2);
        carV2.init();
    }
}

//运行结果
Tire size:17
Tire tread:All-Season Tread
BottomV2 init
FrameworkV2 init.
CarV2 init.

1.2 传统开发 和 IoC 对比总结

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sibXdGq4-1651373641278)(/Users/cxf/Desktop/MarkDown/images/IOC对比传统开发.png)]

理解传统方式:Car --> Framework --> Bottome --> Tire

上级一直在 不停的 new 下级对象 和 调用 init,整个过程是 自顶而下

package old;

public class Car {
    private void init(int tireSize) {
        Framework framework = new Framework();
        framework.init(tireSize);
    }

    public static void main(String[] args) {
        int tireSize = 19;
        Car car = new Car();
        car.init(tireSize);
    }
}

理解IoC:Tire --> Bottom --> Framework --> Car

使用者会提前 new 好需要的下级对象,通过注入的方式传递给上级对象

package v2;

public class App {
    public static void main(String[] args) {
        int tireSize = 17;
        String tireTread = "All-Season Tread";
        TireV2 tireV2 = new TireV2(tireSize, tireTread);
        BottomV2 bottomV2 = new BottomV2(tireV2);
        FrameworkV2 frameworkV2 = new FrameworkV2(bottomV2);
        CarV2 carV2 = new CarV2(frameworkV2);
        carV2.init();
    }
}

IoC和传统开发区别就是依赖的传递相反,不再是上级控制下级;而是通过注入的方式,下级的修改也不会影响上级

1.3 DI概念说明

上文的 IoC 提到的一个新的概念就是 依赖注入「Dependency Injection」

官方的话:所谓的依赖注入就是在 Spring 容器运行期间,动态地把某种依赖关系注入到 Spring容器
翻译过来就是:比如今天我要返校,我可以火车,大巴车,高铁,飞机等等交通工具来解决返校问题。这段话中 返校:就相当于IoC,而 交通工具 则就是 DI

IoC就比如是一种设计思想,指导原则;而 DI 就是实打实的具体方案
IoC 和 DI 从不同角度描述的同一件事:IoC 利用 DI 实现程序之间的解耦

现在我们知道了通过 DI 来把东西放入到 Spring容器 中,下一步就是如何使用。来看一下具体项目流程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值