详解 Spring - Ioc(控制权反转) 和 DI(依赖注入)

目录

Spring 是什么?

Ioc

Ioc 的优点

DI 

Ioc 和 DI 的区别


Spring 是什么?

通常情况下 Spring 是指 Spring Framework (Spring 框架), 是一个开源框架, 有着庞大的社区, 这就是他能长久不衰的原因, Spring 支持广泛的应用场景, 他可以让企业级的应用开发起来更简单

Spring框架旨在简化Java开发,并提供一种灵活的、综合性的解决方案,使得开发者可以专注于业务逻辑的实现,而不用过多关注底层的技术细节。

重点:

Spring 的核心特性 : Spring 是包含了众多工具方法的 IoC 容器

Ioc

IOC是Inversion of Control(控制反转)的缩写,也称为依赖注入(Dependency Injection,DI)。它是一种设计原则和编程模式,用于降低组件之间的耦合度,提高代码的可维护性和灵活性。

在传统的编程模式中,一个对象通常负责创建和管理其依赖的其他对象,这种控制关系由对象自己管理,因此称为控制权在对象内部。而在IOC中,控制权被反转,即由外部容器负责创建和管理对象之间的依赖关系。

具体来说,IOC容器在应用程序启动时负责创建各个对象,并将它们的依赖关系注入到相应的对象中,使得对象之间的耦合度降低。这样一来,对象只需要关注自己的业务逻辑,而不需要关心依赖对象的创建和管理,从而使得代码更加松散耦合、易于测试和维护。

Spring框架的核心功能之一就是提供了一个IOC容器,通过配置文件或注解,开发者可以声明对象之间的依赖关系,让Spring容器来负责对象的创建和依赖注入,从而实现控制反转。这使得Spring成为了一个灵活、可扩展的企业级应用开发框架。

一句话总结:

Ioc (控制权翻转) -> 对象的生命周期,不由程序员(或当前代码)来控制,而是由 Spring (Spring 容器/Ioc 容器)来控制

Ioc 的优点

  1. 降低组件之间的耦合(松耦合):IOC将对象之间的依赖关系交由外部容器来管理,使得组件之间的耦合度降低组件不再直接依赖于具体的实现细节,而是通过接口或抽象类进行交互,这样可以更容易地进行模块的替换和扩展,提高代码的灵活性。

  2. 提高可维护性:通过IOC容器管理对象的依赖关系,代码结构更加清晰和易于理解。在修改或更新依赖的时候,不需要修改大量的代码,只需要调整配置即可,减少了代码的改动范围,从而降低了出错的风险,提高了代码的可维护性。

  3. 易于测试:IOC使得依赖对象的创建和管理与组件的业务逻辑分离,因此在单元测试中可以轻松地使用模拟对象或者假对象来替代真实的依赖对象,从而更加方便地进行单元测试。

  4. 支持松散耦合:IOC容器可以通过配置文件或注解来管理对象的依赖关系,这使得组件之间的耦合度更松散。这种松散耦合使得开发者能够更容易地替换、更新和维护组件,也使得代码更易于复用和扩展。

  5. 提高了代码的可扩展性:由于IOC支持松散耦合和模块化的设计,当需要增加新功能或引入新的组件时,可以更加方便地进行扩展而不需要修改大量现有的代码。

总的来说,IOC的优点在于提高了代码的灵活性、可维护性和可测试性,使得应用程序更易于开发、扩展和维护。这也是为什么IOC在现代的应用程序开发中得到广泛应用的原因。

组件: 一个组件可以是一个独立的类,也可以是一组相关联的类。组件通常用于封装特定的功能或服务,并且具有明确定义的接口,允许其他组件或系统通过该接口与它进行交互。

控制反转我们可以用具体的代码示例来进行举例说明:

实现电脑配件之间的关系

先用传统模式实现,之后和控制反转进行对比

传统模式:

实现思想:

组装一台电脑,需要很多东西,我们举例三者之间的依赖关系,电脑需要依赖机身, 而机身得依赖屏幕等等...我们使用代码实现

package old2;

import ioc.Test;

//电脑类
public class Computer {
    private Framework framework;

    public Computer(int size) {
        this.framework = new Framework(size);
    }

    public void fun() {
        System.out.println("I am computer");
        framework.fun();
    }
}

//机身类
class Framework {
    private Screen screen;
    public Framework(int size) {
        this.screen = new Screen(size);
    }

    public void fun() {
        System.out.println("I am framework");
        screen.fun();
    }
}

//屏幕类
class Screen {
    public int size = 10;
    public Screen(int size) {
        this.size = size;
    }
    public void fun() {
        System.out.println("I am screen size : " + size);
    }

}
//测试类
class Test1 {
    public static void main(String[] args) {
        Computer computer = new Computer(20);
        computer.fun();
    }
}

缺点:

使用传统方法之后, 我只是改了一下屏幕的尺寸, 他依赖的各个组件中都要设置 size 进行改动, 需求要是太多了的话.修改的地方更是越来越多,这就是传统开发中的缺陷

解决办法:

就是,使用控制反转, 我们由自己创建下级类, 改为传递的方式,自己不用创建下级类. 这时候下级类发生了改变我们也无需改动

这样就相当于我们屏幕组件都外包出去, 改的时候只需要给外包公司说一下他就帮我们改了

现在我们用 Ioc(控制反转)思想实现

package ioc2;

public class Computer {
    private Framework framework;

    public Computer(Framework framework) {
        this.framework = framework;
    }

    public void fun() {
        System.out.println("I am computer");
        framework.fun();
    }

}

//机身类
class Framework {
    private Screen screen;
    public Framework(Screen screen) {
        this.screen = screen;
    }

    public void fun() {
        System.out.println("I am framework");
        screen.fun();
    }
}

//屏幕类
class Screen {
    public int size;
    public Screen(int size) {
        this.size = size;
    }
    public void fun() {
        System.out.println("I am screen size : " + size);
    }

}
 //相当与一个Ioc容器
class Test {
    private Computer computer;
    private Framework framework;
    private Screen screen;
    public Test() {
        this.screen = new Screen(10);
        this.framework = new Framework(screen);
        this.computer = new Computer(framework);
    }

     public static void main(String[] args) {
         Test test = new Test();
         test.computer.fun();
     }
}

现在改尺寸的话只需要改一个地方即可,整个调用链不需要改变,实现了解耦

总结: 通过以上的对比我们发现 : 改进之后的控制权发⽣的反转,不再是上级对象创建并控制下级对象了,⽽是下级对象把注⼊将当前对象中,下级的控制权不再由上级类控制了,这样即使下级类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现思想


理解完控制反转之后我们来看看开头说的这句话,Spring 是包含了众多工具方法的 IoC 容器, 既然Spring 是一个容器,那么他就会具备两个最基本的功能

1. 将对象存入到容器中

2. 从容器中取出对象

这就是 Spring 最核心的两个功能, 具体实现的方式就是接下来我们说的 DI ,我们简单来了解一下

DI 

DI代表依赖注入(Dependency Injection),它是控制反转(IoC)的一种具体实现方式。

依赖注入是一种设计模式,通过外部容器(通常是IOC容器)来管理组件之间的依赖关系。在传统的编程模式中,一个对象负责创建和管理其所依赖的其他对象,这样会导致代码高度耦合且难以维护。而在依赖注入中,对象不再负责自己的依赖对象的创建和管理,而是由外部容器来负责,将依赖的对象“注入”到对象中。

依赖注入可以通过构造函数、Setter方法或接口注入等方式来实现。通过依赖注入,对象只需关注自身的业务逻辑,而不需要关心依赖的具体实现细节,从而降低了组件之间的耦合度,提高了代码的可维护性和灵活性。

Spring框架是一个经典的使用依赖注入的例子。通过配置文件或注解,Spring容器负责创建和管理对象之间的依赖关系,从而实现了控制反转和依赖注入。这使得Spring应用程序更易于开发、测试和维护。

Ioc 和 DI 都了解过了之后, 我们来说说 他们两者的区别

Ioc 和 DI 的区别

IOC (Inversion of Control) 和 DI (Dependency Injection) 是软件开发中两个相关但不同的概念。

  1. IOC(控制反转): IOC 是一种软件设计原则,其核心思想是将控制权从一个模块或类的内部转移到外部容器。传统的程序设计中,类通常会自己创建和管理其依赖关系。但在IOC中,类不再自己直接管理依赖关系,而是由外部容器来管理和注入这些依赖关系。这样做的目的是解耦组件之间的依赖,提高代码的可维护性和可扩展性。

  2. DI(依赖注入): DI 是实现IOC的一种具体方式。它是IOC的一种具体实现模式。在DI中,依赖关系不是在类内部通过实例化其他类来创建,而是通过在类的构造函数、属性或方法中传递依赖对象。换句话说,依赖关系是由外部容器注入到类中的。这种方式使得类的使用者不需要关心依赖对象的创建和生命周期,而是由容器来负责。

总结:

  • IOC 是一种设计原则,其核心思想是将控制权从类内部转移到外部容器,从而实现解耦和可维护性。

  • DI IOC的一种具体实现方式,它通过在类的构造函数、属性或方法中传递依赖对象来实现控制反转。DI 是实现IOC的一种手段

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值