思考,输出,沉淀。用通俗的语言陈述技术,让自己和他人都有所收获。
作者:毅航😜
谈及IOC
我想大多数后端开发者一定会想到Spring
,这主要是因为Spring
框架将IOC
设计原则贯穿于整个框架中,并通过依赖注入(DI
)和面向切面编程(AOP
)等特性,实现了一种轻量级、灵活的IOC
容器,进而将所有的Bean
信息都交由容器
管理,进一步避免了开发人员繁琐的使用new
关键字来构建对象,进一步实现解耦的目的。
IOC
的本质
IOC
全称为Inversion of Control
译为中文即控制反转 。有了反转必然便会有正转,这一点就像有反向代理
的出现必然会有正向代理
一样。那什么又是正转
呢?通俗来看,如果我们通过手动方式去创建对象维护对象间的依赖关系的话,那便是正转
。 这样说可能比较晦涩,我们举一个简单的例子来看,例如:
java
@RestController
@RequestMapping("/users")
public class UserController {
private UserService userService = new UserServices()
@PostMapping("/add-user")
public ResponseEntity getBookAndUserInfo(@RequestBody UserInfo userInfo ) {
return userService.addUser(userInfo);
}
在上述例子中,UserController
需要依赖于userService
来完成的对象的操作逻辑,为了实现这一目的,我们通过使用new
关键字的方式在UserController
构建一个名为userService
的对象来满足这一依赖关系。这便是所谓的正转
,即应用程序需要人为主动的去维护对象间的依赖关系,并且自己创建对象。
知晓了正转
后,我们再来看反转
。其实,反转
的核心在于将程序中对象的创建、依赖注入和生命周期管理等控制权转移给外部容器或框架,而不是由程序自身来负责。换言之,IOC
的本质是反转了传统的控制流程,使得程序不再控制对象的创建和管理,而是由外部容器来控制。
通过我们之前对于正转
的介绍,不难发现,在传统的程序设计中,对象之间的依赖关系通常是硬编码在代码中的,即一个对象直接依赖于另一个对象的具体实现。 这进而便导致了对象间高耦合的发生。而IOC
的出现恰恰有效的降低了对象间的耦合关系。
具体到Spring
来看,其通过将对象的创建和管理交给容器来处理,从而降低了对象之间的直接依赖关系,实现了解耦的目的。而在IOC
的设计中,对象之间的依赖关系通常是通过接口或抽象类来定义的,具体的实现则由容器在运行时动态地注入到对象中。
事实上,IOC
容器负责管理应用程序中的各个组件(对象)的生命周期,包括创建、配置、组装、初始化和销毁等过程。开发者只需要在配置文件或注解中声明对象之间的依赖关系,而不需要直接在代码中硬编码依赖关系。
DI:依赖注入
在开始分析两者关系之前,希望你能明白:所谓的依赖注入(Dependency Injection,DI)是控制反转(Inversion of Control,IoC)的一种具体实现方式罢了。 我们知道,在传统的程序设计中,对象通常会在自己的内部负责创建和管理依赖对象,导致了高耦合度和低灵活性。而使用依赖注入的机制引入后,对象不再负责创建和管理依赖对象,而是通过外部容器来将依赖对象注入到目标对象中,从而实现了对象之间的解耦。
事实上,依赖注入的原理很简单,即目标对象不再直接依赖于具体的实现,而是依赖于接口或抽象类。外部容器负责创建依赖对象的实例,并将其注入到目标对象中 。这样一来目标对象只需要声明依赖关系,而不需要关心依赖对象的创建和管理,从而降低了对象之间的耦合度。
总之,DI
与IOC
密切相关,可以说DI
是IOC
的一种具体实现方式。其中IOC
描述了程序中对象控制权的反转,即将对象的创建和管理交给外部容器来处理。而DI
则是实现IOC
的手段之一,它通过依赖注入的方式来实现对象之间的解耦。DI
将对象的依赖关系从对象内部移动到了外部容器中,使得系统更加灵活、可维护和可扩展。
换言之,依赖注入是一种实现IOC
的具体方式,通过将对象之间的依赖关系从对象内部移动到外部容器中,实现了对象之间的解耦,提高了系统的灵活性和可维护性。
IOC思想的应用
正如前文所说,控制反转(IOC
,Inversion of Control)是一种设计思想,因此无论在前端还是后端主流框架都能看到IOC
思想的应用。
在前端主流框架中(如Vue.js、React.js、Angular
等),IOC
思想主要通过依赖注入(DI
,Dependency Injection)来实现。这些框架提供了便捷的方式来管理组件之间的依赖关系,使得开发者可以更轻松地组织和管理代码。通过依赖注入,可以实现组件之间的解耦,提高了代码的灵活性和可维护性。
例如,Vue.js
提倡将应用程序拆分成组件,每个组件负责自己的状态和行为,通过 props
和 events
来实现组件之间的通信,这可以看作是一种轻量级的 IOC
思想,即组件之间的依赖关系由父组件动态地注入给子组件,而子组件则通过事件向上传递状态。这种组件化的设计理念使得Vue.js
应用程序更加灵活、可维护和可扩展。
在后端主流框架中(如Spring、Django、Express
等),IOC
思想主要通过依赖注入容器(DI Container
)来实现。这些框架提供了容器来管理应用程序中的组件,负责对象的创建、配置和生命周期管理等任务。开发者只需要声明组件之间的依赖关系,而不需要直接在代码中进行对象的创建和管理,从而降低了系统的耦合度,提高了代码的可维护性和可测试性。
例如,在Spring
框架中,可以通过注解或者XML
配置文件来声明Bean
和它们之间的依赖关系,而Spring容器则负责实例化和管理这些Bean
。
总结
至此,文章主要介绍了控制反转(IOC
)和依赖注入(DI
)的概念、本质以及它们在现代软件开发中的应用。具体来看,IOC
将对象的创建和管理权交给外部容器,从而降低了对象之间的耦合度,实现了解耦的目的。DI
作为IOC
的具体实现方式,通过依赖注入的方式实现了对象之间的解耦,提高了系统的灵活性和可维护性。
最后,希望文章对你理解控制反转(IOC
)和依赖注入(DI
)有所帮助~~~