IoC
IoC(inversion of Control), 控制反转. 就好像敏捷开发和 SCRUM 一样, 不是什么技术, 而是一种方法论, 一种工程化的思想. 使用 IoC 的思想意味着你将设计好的对象交给容器控制, 而不是传统的在你的对象内部直接控制.
为什么要控制反转呢, 谁在控制谁呢, 反转了什么东西呢? 这篇笔记聊的就是这些东西
谁在控制谁? 一般来讲, 我们直接 new 一个对象, 是我们运行的这个程序去主动的创建依赖对象; 但是 IoC 时会有一个 IoC 容器来负责这些对象的创建. 这个时候 IoC 容器控制了对象, 控制了外部资源获取.
反转了什么呢? 在传统的程序里面, 我们在对象中主动控制去直接获取依赖对象
依赖(在 A 类里面创建了 B 类的实例, 这样 A 依赖于 B)
举例说明下?
在 GitHub 上面看到了一段很有意思的伪代码, 我感觉很能解释 IoC 的关系, 于是就摘抄到这里面来
在生活中, 和一个女孩子认识有三种方法
青梅竹马
- public class Girl{
- void Kiss(){
- Boy RightPerson = new Boy();
- }
- }
这个 RightPerson 最大的缺点就是没办法更换(...), 在 Boy 的整个生命周期里面他都会存在, 如果 Girl 想换一个 boy kiss 呢, 就不是很好了(...)
相亲平台
- public class Girl{
- void Kiss(){
- Boy Boy = BoyFactory.createBoy();
- }
- }
这个 Boy 是不是 RightPerson 就不知道了, 但是不满意就换. 但是我们现在有了一个 Boy Factory, 这很烦, 有外人 / 平台介入了日常生活, 它以单例模式或者是存在于全局.
值得信赖的人安排, 只需要守株待兔
- public class Girl{
- void kiss(Boy boy){
- boy.kiss();
- }
- }
你传什么给我, 我就和什么 Kiss(表达有点不大合适, 但是也想不出什么好词了), 至少这种方式 Girl 和 Boy 不用忙活了.
这就是 IoC 的基本思想, 将对象的创建和提取到外部, 由外部容器提供所需要的组件.
为什么要使用 IoC 呢
说实话,"高内聚, 低耦合" 这句话我都听到吐了. 每个上过软件工程导论课的同学都能跟你侃侃而谈五分钟. 那接着往下问 "什么是内聚, 什么是耦合"" 为什么要倡导松耦合的设计, 这跟面向对象设计法则又有什么关系呢?"
有了 IoC 容器后, 把创建和查找依赖对象的控制权交给了容器, 由容器进行注入组合对象, 所以对象与对象之间的耦合是松散的, 这样也方便测试, 利于功能复用, 更重要的是使得程序的整个体系结构变得非常灵活.
IoC 相当于是将应用程序赋予给了一个中心, IoC 容器.
DI
都提到 IoC 了, 怎么能少得了 DI(Dependency Injection ), 注入依赖或者依赖注入? anyway, 随便你. 组件之间的依赖关系由容器在运行过程中规定. 具象化一点, 各个组件的依赖关系是由容器来注入的. 开发者依赖这个机制, 只需要通过配置指定资源, 完成业务逻辑即可, 不用关心具体的资源来自何方, 由谁实现(依然是面向对象的思想)
那么, 你说的这个 DI 和 IoC, 他们有区别吗?
有区别, 但是其实 DI 和 IoC 说的是一个东西, 因为 IoC 这个东西说的模模糊糊, Martin Fowler(XP 的提出者之一, 敏捷方法的创始人)在 2004 提出了 DI 的概念,"依赖注入" 明确描述了 "被注入对象依赖 IoC 容器配置依赖对象".
Martin Fowler 的原文是这样的, 在 inversion of Control 这一节里面, 他提到
As a result I think we need a more specific name for this pattern. Inversion of Control is too generic a term, and thus people find it confusing. As a result with a lot of discussion with various IoC advocates we settled on the name Dependency Injection.
IoC 是我们想要做的事情, 每个框架都说自己 IoC,DI 是我们采取的手段
我摘了一段知乎的回答, 问题的链接贴在下面, 有些回答举了一些具体的例子, 很有利于理解
IoC 的思想最核心的地方在于, 资源不由使用资源的双方管理, 而由不使用资源的第三方管理, 这可以带来很多好处.
第一, 资源集中管理, 实现资源的可配置和易管理.
第二, 降低了使用资源双方的依赖程度, 也就是我们说的耦合度.
AOP(Aspect-Oriented Programming)
我们都知道 Spring 的 AOP 是这个框架的重要组成部分 , 那 AOP, 面向切面编程又是在做什么呢?
在面向对象的思想里面 (Object-Oriented Programing) 有三大法宝,"封装, 继承, 多态", 用这三大法宝建立了对象的层次, 但是它是一个纵向的结构, 有比较明确的上下级关系, 但是在平行的层次中发挥不出太大的作用.
所以我们又需要一种横向的结构来定义这些平行的关系, 以日志记录为例, 记录日志一般要在操作完毕之后, 用 OOP 的思想, 那我就要去项目的每个操作数据库的方法的里面去加上保存日志, 这会导致代码重复, 模块的重用会因此受到影响.
如果使用 AOP, 只需要自定义一个方法, 在 spring 配置文件中将该方法配置好, 当每次调用完原先的 save 方法时, 都会去执行你写的保存日志方法.
它将程序中的交叉业务逻辑 (日志, 事务等), 封装成一个切面, 然后注入到目标对象(具体业务逻辑) 中去.
参考
《Spring 实战》
Spring IoC 有什么好处呢 (这里面有一些回答很有参考价值, 仔细看看发现自己以前的理解还是有问题)
- Inversion of Control Containers and the Dependency Injection pattern https://martinfowler.com/articles/injection.html
- IoC
来源: https://www.cnblogs.com/QuixoteY/p/11170263.html