Spring学习---控制反转和依赖注入
什么是IoC(控制反转)
IoC(Inversion of Control)的意思是“控制反转”,它是Spring最核心的点,并且贯穿始终。IoC并不是一门技术,而是一种设计思想。在Spring框架中实现控制反转的是Spring IoC容器,其具体就是由容器来控制对象的生命周期和业务对象之间的依赖关系,而不是像传统方式(new 对象)中由代码来直接控制。程序中所有的对象都会在Spring IoC容器中登记,告诉容器你是个什么,你需要什么,然后IoC容器会在系统运行到适当的时候,把你要的对象主动给你,同时也把你交给其它需要你的对象。也就是说控制对象生存周期的不再是引用它的对象,而是由Spring IoC容器来控制所有对象的创建、销毁。对于某个具体的对象而言,以前是它控制其它对象,现在是所有对象都被Spring IoC容器所控制,所以这叫控制反转。
控制反转最直观的表达就是,IoC容器让对象的创建不用去new了,而是由Spring自动生产,使用java的反射机制,根据配置文件在运行时动态的去创建对象以及管理对象,并调用对象的方法。控制反转的本质是控制权由应用代码转到了外部容器(IoC容器),控制权的转移即是所谓的反转。控制权的转移带来的好处就是降低了业务对象之间的依赖程度,即实现了解耦。即然控制反转中提到了反转,那么肯定有正转,正转和反转有什么区别呢?我曾经在博客上看到有人在面试的时候被问到Spring IoC知识点:什么是反转、正转?
- 正转:如果我们要使用某个对象,就需要自己负责对象的创建。
- 反转:如果要使用某个对象,只需要从Spring 容器中获取需要使用的对象,不关心对象的创建过程,也就是把创建对象的控制权反转给了Spring框架。
3、什么是DI(依赖注入)
DI(Dependency Injection)的意思是"依赖注入",它是IoC(控制反转)的一个别名为。在早些年,软件开发教父Martin·Fowler
在一篇文章中提到将IoC改名为 DI,这是原文地址:https://martinfowler.com/articles/injection.html。其中有这样一段话,如下图所示:
意思是:他认为需要为该模式(IoC)指定一个更具体的名称。因为控制反转是一个过于笼统的术语,所以人们会感到困惑。他与IoC的倡导者进行了大量讨论之后,然后他们决定使用依赖注入这个名称。也就是在这时DI(依赖注入)这个词被大家知晓。我在第一章的时候也提到过,IoC和DI其实是同一个概念,只是从不同的角度描述罢了(IoC是一种思想,而DI则是一种具体的技术实现手段)。
这是我们在其它地方看到的一句话,这句话真的是醍醐灌顶,一句话就把其它人一大堆很难懂的话给说清楚了:IoC是目的(它的目的是创建对象),DI是手段(通过什么手段获取外部对象)。所以至此我们别再傻傻分不清楚IoC和DI了。
依赖注入:即应用程序在运行时依赖IoC容器来动态注入对象需要的外部资源。依赖注入中"谁依赖谁,为什么需要依赖,谁注入谁,注入了什么",下面来深入分析一下:
●谁依赖于谁:当然是应用程序依赖于IoC容器;
●为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源;
●谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;
●注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。
综合上述,我们可以用一句话来概括:所谓Spring IoC/DI,就是由 Spring 容器来负责对象的生命周期和对象之间的依赖关系。
4、对SpringIoC的理解
上面已经详细介绍了IoC和DI的基本概念,为了更好的理解它们,所以接下来用一个生活中的例子来加深理解。在举例之前,先要搞清楚,依赖关系的处理方式有两种:
- 主动创建对象
- 被动创建对象
①、主动创建对象
我们知道,在传统的Java项目中,如果需要在一个对象中内部调用另一个对象的方法,最常用的就是在主体类中使用new 对象
的方式。当然我们也可以使用简单工厂模式来实现,就是在简单工厂模式中,我们的被依赖类由一个工厂方法创建,依赖主体先调用被依赖对象的工厂方法,接着主动基于工厂访问被依赖对象,但这种方式任然存在问题,即依赖主体与被依赖对象的工厂之间存在着耦合。主动创建对象的程序思想图如下所示:
举例:这是我在购买的《Java EE 互联网轻量级框架整合开发》一书中看到的一个栗子,我觉得作者的这个栗子通俗易懂,因为它源自生活。例如我们平时想要喝一杯柠檬汁,在不去饮品店购买的情况下,那么我们自己想要的得到一杯橙汁的想法是这样的:买果汁机、买橙子,买杯子,然后准备水。这些都是你自己"主动"完成的过程,也就是说一杯橙汁需要你自己创造。如下图所示:
②、被动创建对象
由于主动创建对象的方式是很难避免耦合问题,所以通过思考总结有人通过容器来统一管理对象,然后逐渐引起了大家的注意,进而开启了被动创建对象的思潮。也正是由于容器的引入,使得应用程序不需要再主动去创建对象了,可见获取对象的过程被反转了,从主动获取变成了被动接受,这也是控制反转的过程。被动创建对象的程序思想图如下所示:
举例:在饮品店如此盛行的今天,不会还有人自己在家里制作饮品、奶茶吧!所以我们的首选肯定是去外面购买或者是外卖。那此时我们只需要描述自己需要什么饮品即可(加冰热糖忽略),不需要在乎我们的饮品是怎么制作的。而这些正是由别人"被动"完成的过程,也就是说一杯饮品需要别人被动创造。如下图所示:
通过上图的例子我们可以发现,我们得到一杯橙汁并没有由自己"主动"去创造,而是通过饮品店创造的,然而也完全达到了你的要求,甚至比你创造的要好上那么一些。
上面的例子只能看出不需要我们自己创建对象了,那万一它还依赖于其它对象呢?那么对象之间要相互调用呢?我们要怎么来理解呢?下面接着举例。
假如这个饮品店的商家是一个奸商,为了节约成本,它们在饮品中添加添加剂,举例如下图所示:
在主体对象依赖其它对象的时候,对象之间的相互调用通过注入的方式来完成,所以下面我们介绍IOC中的三种注入方式。
至此为止对Spring IOC/DI的理解已经全部介绍完了,也不知道你们看没看懂,或者是我本身理解有误,还请大家多多指教!!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了