看一个生活中的例子:
项目组向资源管理者申请资源,资源管理者向资源池协调资源,资源池分配资源给项目组,资源是资源池分配给项目组,而不是项目组自己招人。
这里的好处显而易见,就是项目组不需要关注招人,面试,谈待遇等等一堆事情,只需要提出用人要求就可以。
对应到代码中:
Class A使用到了Class B,但Class B不是被Class A创建,Class A只需声明要使用Class B,由容器创建Class B并注入A,创建Class B的控制权不在Class B的调用者Class A上,而是容器,这就是控制反转。
这里的好处是Class A不需要关注要使用的类如何创建,只需要声明要使用该类则可,由容器来创建并注入这个类。
而容器怎么分配Class B给Class A就引出了依赖注入(DI)。
容器要想注入Class B给Class A的几种方式:
1.构造器注入:
Class A private B b; @Autowired public A(B b) { this.b = b; } } 复制代码
2.参数注入
Class A @Autowired public void exec(B b) { b.doSomeThing(); } } 复制代码
3.属性注入
Class A @Autowired private B b; public void exec() { b.doSomeThing(); } } 复制代码
本质的好处是解耦,而Spring的依赖注入体现为以下好处:
1.容易测试,依赖的对象是注入的,因此可以在单元测试时Mock一个对象并注入来测试
比较以下代码:
Class A { public void exec() { B b = new B(); b.doSomeThing(); } } Class A { public void exec(B b) { b.doSomeThing(); } } 复制代码
第一种方式Class B是在方法内部自行构建的,测试时没有办法Mock,而第二种方式则可以Mock Class B后传入。
2.不需要自己实现单例模式,Spring中的Bean默认都是单例模式,单例的作用是减少类实例,从而减少内存占用,并且不用每次使用时都重新实例化,提高效率。
3.基于依赖注入使得容器可以统一管理Bean以及Bean的生命周期,在Bean的生命周期管理时,可以统一实现一些通用的公共逻辑,而不需要每个Bean单独再实现一遍。
end.
站点: javashizhan.com/
微信公众号: