要理解依赖注入(Dependency Injection), 控制反转(Inversion of Control), 控制反转容器(IoC Container), 首先要知道依赖倒置原则(Dependency Inversion Principle)
依赖倒置原则: 把原本的高层建筑依赖底层建筑”倒置”过来,变成底层建筑依赖高层建筑. 原来是 Controller -> Service, 改成 Controller <- Service. 顶层方法要什么, 底层方法去实现, 顶层方法不管底层是怎么实现的, 最后拿来给我用就行, 避免牵一发而动全身.
非依赖注入的原始代码
1 | class Controller { |
需求: 如果要改变 Service, 那么同时要改 Controller
1 | class Service { |
基于依赖注入的代码
1 | class Controller { |
同样的改变需求
1 | class Controller { |
可以看到, 只有与 Service 相关的部分作出了修改.
下面说说什么是依赖注入 & 控制反转
就像上面一样, Controller 是需要依赖 Service 的.
正常是把 Service 的创建放在 Controller 中, 依赖注入 就是把依赖的部分当做参数传入进去.
原来是 Controller 控制 Service 的创建和生命周期, 控制反转 就是 Service 控制了 Controller 的创建和生命周期.
Ps: 说是控制, 实际上 Controller 的创建需要依赖于 Service 的存在; Service 生命周期结束, Controller 即使在内存还在, 也无法使用, 名存实亡.
控制反转容器
非依赖注入的写法
1 | const c = new Controller(size); |
依赖注入的写法
1 | const s = new Service(size); |
将依赖注入创建 Controller 的所有过程, 打包成一个整体, 基于配置文件或者外部参数控制的容器化方法, 即为控制反转容器
1 | const ctlrFactory = (size) => { |
控制反转容器的几种写法
直接注入依赖类对象
1 | class Service {} |
定义依赖接口, 注入实现接口的子类.
1 | interface Service {} |
参考文档
Spring IoC有什么好处呢 中 Mingqi 的回答.