首页 > 其他分享 >如何理解Spring的IOC和DI

如何理解Spring的IOC和DI

时间:2023-07-22 22:24:04浏览次数:31  
标签:容器 依赖 run DI 对象 Spring IOC

学习过Spring框架的人一定都会听过Spring的IoC(控制反转) 、DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IOC 、DI这两个概念是模糊不清的,是很难理解的。今天我就谈谈我对IOC和DI的理解,希望对大家有帮助。

1、IOC与DI介绍

IOC 是 Inversion of Control 的缩写,翻译成中文是“控制反转”的意思。它不是一个具体的技术,而是一种设计思想。

它主要是为了解决程序里对象解耦的。

那什么是解耦呢?要解释什么是解耦,那就得先了解什么是耦合。

所谓的耦合是指:两个或者两个以上的对象存在依赖,当一方修改之后会影响另一方,那就可以说这些对象间存在耦合。

比如对象A中需要使用对象B的某个方法,我们通常的使用方法是这样的:

class A {
	public void run(){
		B b = new B();
         b.run()
	}
}

class B {
	public B(){
		//执行过程省略
	}
	public void run(){
		//执行过程省略
	}
}

现在A对象和B对象就存在耦合,因为如果后面由于业务需求变更,B对象需要传入C对象才可以执行,所以我们不得不修改构造方法,那么A对象的run方法也要做相应的改变。代码改动如下:

class B {
	private C c;
	
	public B(C c){
		//执行过程省略
	}
	public void run(){
		//执行过程省略
	}
}

此时的B的构造方法一定需要传入C对象,那么之前A对象run方法也需要new 一个C对象,传入给B。这是开发中经常遇到的问题,如果只是A对象run用到了B,那么我们改一下就好,但是如果我们有几十处需要new B呢,那么这修改量就特别麻烦。

所以解耦就是为了解决,上述例子的问题,解除对象之间修改后影响另一方的问题。

那我们要怎么解决呢?

我们可以通过将对象传递而不是new对象的方式来解决,比如这样

class A {
	private B b;
	
	public void A(B b){
		this.b = b;
	}
	
	public void run(){
         b.run()
	}
}

这样改造之后,无论B的构造方法怎么修改,即使后面加更加多的参数,而调用它的类A都无需任何修改,这样就实现的对象的解耦。

那么B对象谁来new呢?

答案就是Spring的IOC容器,IOC容器实际上就是一个存放各种对象的map,在项目启动的时候会读取配置文件里面的bean节点或者扫描类上的注解,通过反射new对象放到这map里。当某个对象需要依赖其他对象时,就通过将依赖对象传递给当前对象,这就到达了解耦。而这种技术就是我们所说的DI(依赖注入)。

DI 是 Dependency Injection 的缩写,翻译成中文是“依赖注入”的意思。依赖注入是实现IOC的一种具体技术 ,它是在IOC运行期间,动态的将某个对象注入到当前对象的技术

所以由此我们可以看出,IOC是一种思想,依赖注入是一种具体的实现方式。

2、控制反转与依赖注入的概念理解

那大家可能有疑问,那为什么要叫控制反转呢?

由上述例子可以看出,一开始对象A使用对象B的时候是通过new创建对象的,是A主动去创建依赖对象B。而在引入IOC后,创建对象已经不是由A创建,而是由IOC容器去创建。也就是说,一开始对象B的创建是由A控制的。而当对象B交由IOC容器创建,并注入给A,对象B的创建和注入就由IOC容器控制了,对象A只是被动的接受依赖对象B。

所以控制反正可以理解为,创建对象的控制权进行转移,以前创建对象的主动权和创建时机是由自己控制的,而现在这种权利转移到了第三方。比如转移给了IOC容器。换种说话就是,控制获得依赖对象的方式反转了。

那么依赖注入就好理解了,就是动态的向某个对象提供它所需的其他对象

3、总结

IOC不是什么技术,而是一种设计思想,在spring中,对象的创建和注入是由IOC容器控制的,这就实现了对象控制权的反转。由我们对对象的控制变成了IOC容器对对象的控制。DI是IOC的具体实现。程序把依赖交给容器,容器帮你管理依赖。

标签:容器,依赖,run,DI,对象,Spring,IOC
From: https://www.cnblogs.com/pjfblog/p/17574406.html

相关文章

  • RabbitMQ(三)整合SpringBoot
    RabbitMQ(三)整合SpringBoot1整合RabbitMQ1导入依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>2查看容器的自动配置......
  • Android Studio 的build窗口 build ouput 显示乱码的解决办法
     help窗口 点击 edit 然后在下面添加  -Dfile.encoding=UTF-8 重启android studio即可......
  • mysql 8.0 Data Dictionary initialization failed.
    MySQL8.0数据字典初始化失败MySQL是一种常用的关系型数据库管理系统,广泛应用于各种应用程序中。然而,有时在使用MySQL时,可能会遇到一些错误和问题。其中一个常见的错误是“mysql8.0DataDictionaryinitializationfailed.”。问题描述当尝试启动MySQL服务器时,可能会收到以下......
  • 10道SpringBoot面试题
    SpringBoot我是JavaPub,专注于面试、副业,技术人的成长记录。以下是SpringBoot面试题,相信大家都会有种及眼熟又陌生的感觉、看过可能在短暂的面试后又马上忘记了。JavaPub在这里整理这些容易忘记的重点知识及解答,建议收藏,经常温习查阅。评论区见本系列《最少必要面试题》Sprin......
  • 如何动态修改 spring aop 切面信息?让自动日志输出框架更好用
    业务背景很久以前开源了一款auto-log自动日志打印框架。其中对于spring项目,默认实现了基于aop切面的日志输出。但是发现一个问题,如果切面定义为全切范围过大,于是v0.2版本就是基于注解@AutoLog实现的。只有指定注解的类或者方法才会生效,但是这样使用起来很不方便。......
  • 带历史记忆,并模糊带出功能的Edit
    就像Chrome网址输入栏一样记录历史网址一样链接:https://pan.baidu.com/s/17ZqzqiFrdBdIeNe-vTzg0Q提取码:zbm41[输入时,若历史记录中有,则实时带出,模糊记录(部分包含),按向下键,可以选择历史项,2]若历史记录没有,按回车,则加入到历史记录中,下次输入则会带出来 以后添加功能,模......
  • SpringBoot整合Liquibase
    1、是什么?Liquibase官网Liquibase是一个开源的数据库管理工具,可以帮助开发人员管理和跟踪数据库变更。它可以与各种关系型数据库和NoSQL数据库一起使用,并提供多种数据库任务自动化功能,例如数据库迁移、版本控制和监控。Liquibase还提供了一个Web界面,可以方便地管理和跟踪数据库......
  • SpringBoot2.x—SpringCache的使用
    SpringCache(1)集成声明式与编程式说起SpringCache您可能不清楚。但您绝对清楚事务。一般使用事务分为编程式和声明式。编程式:事务操作与业务代码耦合,一般我们不会使用这种方式;声明式:AOP的运用,通过注解使得事务代码与业务代码解耦,目前项目中一般都是使用事务注解。而我们平时......
  • 记录--关于前端的音频可视化-Web Audio
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助背景最近听音乐的时候,看到各种动效,突然好奇这些音频数据是如何获取并展示出来的,于是花了几天功夫去研究相关的内容,这里只是给大家一些代码实例,具体要看懂、看明白,还是建议大家大家结合相关API文档来阅读这篇文章......
  • python,is_dir()
    Python中的os.path.isdir()函数在Python编程语言中,os.path模块提供了一系列用于处理文件路径的函数。其中之一就是os.path.isdir()函数,它用于检查一个路径是否为目录。什么是目录?在计算机中,目录是一种用于组织和存储文件和其他目录的文件系统结构。目录可以包含其他目录和文件,形......