前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >IoC与DI的不同和它们分别的作用

IoC与DI的不同和它们分别的作用

原创
作者头像
可大可小
修改于 2021-03-11 09:54:37
修改于 2021-03-11 09:54:37
73200
代码可运行
举报
运行总次数:0
代码可运行

大多数人可能搞混这两个术语。可能是由于在Spring中大量使用了这些概念而导致的混乱,其中使用了Inversion of Control来启用依赖注入。

这篇文章旨在以一种简单的方式来解释这两种说法。 

控制反转

基本概念

IoC的非正式定义:“ IoC是当你让其他人为你创建对象时。” 因此 ,该对象不是由你的代码编写“ new MyObject”,而是由其他人创建的。此 “其他人” 通常称为IoC容器

这个简单的解释说明了一些非常重要的想法:

  1. 之所以称为IoC,是因为对对象的控制被反转了,不是程序员,而是其他人控制对象。
  2. IoC是相对的,因为它只适用于应用程序的某些对象。所以有些对象可能有IoC,而有些对象则由程序员直接控制。

除了Spring之外,还有其他IoC示例,例如 Java Servlet 和 Akka Actors

细节

让我们进一步研究IoC的定义。IoC不仅仅是对象创建:Spring Context或Servlet容器不仅可以创建对象,而且可以管理对象的整个 生命周期。这包括创建对象,销毁它们以及在对象生命周期的不同阶段调用对象的某些方法。这些方法通常称为 回调。再次注意术语:容器调用的方法是回调,而不是 程序员对自己的代码进行的 直接调用

前面提到的所有IoC容器都实现某种生命周期:  Spring Bean生命周期,  Servlet生命周期和 Akka Actor生命周期

要考虑的另一件事是,尽管程序员放弃了对对象的控制,但是他们仍然需要定义 IoC容器用于创建所述对象的 模板

例如,在Spring中,类使用@Service 或 @Component进行注释 (还有许多其他注解 ),以表示Spring容器将管理这些类的实例(也可以使用XML配置代替注释)。Spring管理的对象称为Bean。

在Servlet应用程序中,任何实现Servlet 接口的类 都将由Servlet容器管理。

在Akka应用程序中,IoC容器称为 ActorSystem  ,托管对象是扩展特征Actor的类的实例,  并通过称为Props的配置对象创建 。

这是到目前为止讨论的想法的简要摘要:

  1. IoC容器控制和管理某些对象的生命周期:创建,销毁和回调调用。
  2. 程序员必须确定要由IoC容器管理其实例的类。有几种方法可以执行此操作:使用批注,通过扩展某些特定的类,使用外部配置。
  3. 程序员可以在一定程度上影响IoC容器管理对象的方式。通常,这是通过覆盖对象回调的默认行为来实现的。

Ioc容器

管理对象名称

管理对象定义

Spring Container

Bean

Classes defined with annotations/XML configuration

Servlet Container

Servlet

Classes implementing interface Servlet

Actor System

Actor

Classes extending trait Actor

到目前为止,我们已经解释了IoC,还没解释依赖注入(DI)。 

依赖注入

依赖注入已成为现代软件工程的基石之一,因为它是允许进行适当测试的基础。简而言之,拥有DI与拥有硬编码的依赖关系相反。

代码语言:java
AI代码解释
复制
//硬编码
public class MyClass { 
    private MyDependency myDependency = new MyDependency(); 
}

//依赖注入
public class MyClass { 
    private MyDependency myDependency;

    public MyClass(MyDependency myDependency){
        this.myDependency = myDependency;
    }
}

依赖项可以通过几种方式注入,例如构造函数中的参数或通过“ set”方法。

与DI一样重要的是,它的使用也有一个缺点,即:依赖项的管理很不方便。举个个例子:MyClass1依赖于MyClass2,而MyClass3则取决于:

代码语言:java
AI代码解释
复制
public class MyClass3 {
    public void doSomething(){}
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//MyClass2 依赖 MyClass3
public class MyClass2 {
    private MyClass3 myClass3;

    public MyClass2(MyClass3 myClass3){
        this.myClass3 = myClass3;
    }

    public void doSomething(){
        myClass3.doSomething();
    }
}
代码语言:java
AI代码解释
复制
//MyClass1 依赖on MyClass2
public class MyClass1 {
    private MyClass2 myClass2;

    public MyClass1(MyClass2 myClass2){
        this.myClass2 = myClass2;
    }

    public void doSomething(){
        myClass2.doSomething();
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Main {

    public static void main(String[] args) {

        //All dependencies need to be managed by the develope
        MyClass3 myClass3 = new MyClass3();
        MyClass2 myClass2 = new MyClass2(myClass3);
        MyClass1 myClass1 = new MyClass1(myClass2);

        myClass1.doSomething();
    }
}

现在,让我们假设更进一步,MyClass2需要一个新的依赖项:MyClass4。我们需要进行修改来解决这个新的依赖关系:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class MyClass2 {
    private MyClass3 myClass3;
    private MyClass4 myClass4;

    public MyClass2(MyClass3 myClass3, MyClass4 myClass4){
        this.myClass3 = myClass3;
        this.myClass4 = myClass4;
    }

    public void doSomething(){
        myClass3.doSomething();
        myClass4.doSomething();
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Main {

    public static void main(String[] args) {

        MyClass4 myClass4 = new MyClass4();
        MyClass3 myClass3 = new MyClass3();
        MyClass2 myClass2 = new MyClass2(myClass3, myClass4);
        MyClass1 myClass1 = new MyClass1(myClass2);

        myClass1.doSomething();
    }
}

尽管这个例子中描述的情况还不错,但是现实应用程序可能在整个代码库中分散了几百个依赖项,就像上面的示例一样,它们的创建和管理将需要集中化。

控制反转和依赖注入一起发挥作用

我们刚刚讨论了在应用程序中管理数百个依赖关系的问题,其中可能包含非常复杂的依赖关系图。

因此,这就是IoC的主要作用。使用IoC,依赖项由容器管理,从而减轻了程序员的负担。

使用@Autowired之类的注释 ,要求容器在需要的地方注入依赖项,并且程序员不需要自己创建/管理这些依赖项。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class MyClass1 {

    @Autowired
    private MyClass2 myClass2;

    public void doSomething(){
        myClass2.doSomething();
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class MyClass2 {

    @Autowired
    private MyClass3 myClass3;
    @Autowired
    private MyClass4 myClass4;

    public void doSomething(){
        myClass3.doSomething();
        myClass4.doSomething();
    }
}

结论

我们已经将控制反转和依赖注入作为单独的概念进行了介绍,并说明了在某些情况下如何可以将这两个概念结合起来一起使用

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Spring 的奇幻起源:从 IoC 容器到 Bean 的魔法世界 ✨
大家好这里是苏泽,一个从小喜欢钻研原理的疯小子 这篇文章是我的专栏《Spring 狂野之旅:底层原理高级进阶》 🚀 的第一篇文章 也是学习写一个讲解底层原理的博客的第一课 我认为深入了解一个事物的全貌是一件神秘而刺激的过程 希望你们能和我一样Enjoy the process 这个专栏里我希望能把Spring的底层原理讲得彻彻底底 让普通人也能一看就懂的程度 会慢慢更新 如果有想法可以在评论区提哦 相互交流学习的小伙伴可以关注一下我 技术博客每日一更
苏泽
2024/03/01
1610
Spring之IoC(控制反转)与DI(依赖注入)
本博客将深入探讨控制反转(IoC)和依赖注入(DI)的概念与原理。我们将讨论如何通过XML和注解配置IoC容器,解释Bean的生命周期和作用域,并提供代码示例和注释。此外,还将强调注意事项,并在最后总结所讨论的内容。
默 语
2024/11/20
1960
【JAVA】让 ChatGPT 来描述 IOC
面试过 Java 工程师的小伙伴都知道,Spring 中的 IOC 是面试高频题,面试官上来就问,知道什么是 IOC 吗,IOC 是如何初始化的,以及 Bean 的生命周期等相关内容。
sidiot
2023/08/30
1800
【JAVA】让 ChatGPT 来描述 IOC
Spring 系列之 Spring Framework 中的 IoC 容器
Spring Framework 是一个开源的 Java 应用程序开发框架,它为企业级应用程序提供了一种全面的解决方案。其中的 IoC(Inversion of Control)容器是 Spring Framework 的核心组件之一,它通过控制反转的思想帮助开发者管理和组织应用程序中的对象。
Java极客技术
2024/02/22
2710
Spring 系列之 Spring Framework 中的 IoC 容器
IOC --- 控制反转
IOC,全称为 Inversion of Control(控制反转),是一种重要的编程思想,它可以帮助我们更好地管理程序中的依赖关系。在IOC的基础上,依赖注入(Dependency Injection,DI)是一种实现IOC的技术手段,它可以提高代码「可测试性」,「可维护性」,「可拓展性」。
Niuery Diary
2023/10/22
2210
IOC --- 控制反转
Java Spring Boot中的AOP、DI和IOC
AOP是一种编程范式,它允许开发人员将横切关注点(cross-cutting concerns)从业务逻辑中分离出来,例如日志记录、性能监控、事务管理等。在Spring Boot中,AOP通过切面(Aspect)和通知(Advice)实现。
GeekLiHua
2025/01/21
1340
IOC容器对Bean的生命周期
https://cloud.tencent.com/developer/article/2304343
疯狂的KK
2023/07/24
2620
IOC容器对Bean的生命周期
深入理解DIP、IoC、DI以及IoC容器
摘要 面向对象设计(OOD)有助于我们开发出高性能、易扩展以及易复用的程序。其中,OOD有一个重要的思想那就是依赖倒置原则(DIP),并由此引申出IoC、DI以及Ioc容器等概念。通过本文我们将一起学习这些概念,并理清他们之间微妙的关系。 ---- 目录 前言 依赖倒置原则(DIP) 控制反转(IoC) 依赖注入(DI) IoC容器 总结 ---- 前言 对于大部分小菜来说,当听到大牛们高谈DIP、IoC、DI以及IoC容器等名词时,有没有瞬间石化的感觉?其实,这些“高大上”的名词,理解起来也并不是那么的难
刘皓
2018/04/03
1.2K0
深入理解DIP、IoC、DI以及IoC容器
IOC控制反转与DI依赖注入
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
全栈程序员站长
2022/08/31
2090
IOC控制反转与DI依赖注入
深入理解 Spring IoC 和 DI:掌握控制反转和依赖注入的精髓
控制反转是软件工程中的一个原则,它将对象或程序的某些部分的控制权转移给容器或框架。我们最常在面向对象编程的上下文中使用它。
小万哥
2023/08/11
6560
深入理解 Spring IoC 和 DI:掌握控制反转和依赖注入的精髓
spring的DI/IOC机制
IOC(DI):其实这个Spring​​架构​​核心的概念没有这么复杂,更不像有些书上描述的那样晦涩。​​Java​​程序员都知道:java程序中的每个业务逻辑至少需要两个或以上的对象来协作完成,通常,每个对象在使用他的合作对象时,自己均要使用像new object() 这样的语法来完成合作对象的申请工作。你会发现:对象间的耦合度高了。而IOC的思想是:Spring容器来实现这些相互依赖对象的创建、协调工作。对象只需要关系业务逻辑本身就可以了。从这方面来说,对象如何得到他的协作对象的责任被反转了(IOC、DI)。
张哥编程
2024/12/17
590
深入理解DIP、IOC、DI
DIP软件架构设计原则。仅告诉你两个模块应该如何依赖,但不告诉你如何做。IoC则是一种软件设计模式,它告诉你应该如何做
西柚dzh
2022/06/09
4670
Java注解之@Autowired
在Java中,@Autowired注解的作用是将依赖关系自动注入到类中,它是Spring框架中的一个核心注解之一。@Autowired可以用于自动装配一个类的成员变量、构造函数或者方法,以实现依赖注入(Dependency Injection)。
用户4396583
2024/08/09
6470
Spring 复盘 | IOC
全面进入复习模式,从 Spring 开始。Spring 是一个轻量级的开源框架,是为解决企业应用开发的复杂性而创建的。我很不喜欢这种略显官方的说辞。千人千面,每个人对技术的理解都不一样。而在我的理解中,Spring 的主要就解决了两件事情(当然它还解决了数据访问、远程调用、单元测试等问题),分别对应 Spring 的两个设计思想 IOC 和 AOP:
JavaFish
2019/10/17
3560
ASP.NET Core 依赖注入基本用法
ASP.NET Core从框架层对依赖注入提供支持。也就是说,如果你不了解依赖注入,将很难适应 ASP.NET Core的开发模式。本文将介绍依赖注入的基本概念,并结合代码演示如何在 ASP.NET Core中使用依赖注入。
拓荒者IT
2019/09/24
2.1K0
ASP.NET Core 依赖注入基本用法
学完这篇依赖注入,与面试官扯皮就没有问题了。
讨论控制反转之前,先看看软件系统提出控制反转的前世今生。 一个完整精密的软件系统,组件之间就像齿轮,协同工作,相互耦合。
有态度的马甲
2020/10/30
1.3K0
学完这篇依赖注入,与面试官扯皮就没有问题了。
理解Spring中的IoC和DI
在没有IoC之前,我们要在A类中使用B类,就要在A类中new出B类的实例,这样A类和B类之间就出现了耦合。
超超不会飞
2020/09/18
5510
IOC 控制反转[通俗易懂]
Spring Framework 概述https://blog.csdn.net/centrl/article/details/115519480
全栈程序员站长
2022/07/04
5080
【JavaEE进阶】Spring核心与设计思想
我们通常所说的 Spring 指的是 Spring Framework(Spring 框架),它是⼀个开源框架,有着活跃⽽庞⼤的社区,这就是它之所以能⻓久不衰的原因.Spring ⽀持⼴泛的应⽤场景,它可以让 Java 企业级的应⽤程序开发起来更简单. ⽤⼀句话概括 Spring: Spring 是包含了众多⼯具⽅法的IoC容器.
xxxflower
2023/10/16
2630
【JavaEE进阶】Spring核心与设计思想
【SpringBoot】从零开始全面解析Spring Ioc&DI (一)
容器是用来容纳某种物品的(基本)装置。⸺来自:百度百科 生活中的水杯, 垃圾桶, 冰箱等等这些都是容器. 之前接触的容器有哪些? List/Map -> 数据存储容器 Tomcat -> Web 容器
用户11369350
2025/05/25
1320
【SpringBoot】从零开始全面解析Spring Ioc&DI (一)
相关推荐
Spring 的奇幻起源:从 IoC 容器到 Bean 的魔法世界 ✨
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验