控制反转(IOC):Spring容器为对象设置属性的方式
依赖注入:在程序运行过程中,如果需要另一个对象协作时,无需在代码中创建被调用者,而是依赖于外部容器注入。Spring的依赖注入对调用者和被调用者几乎没有任何要求,完全依赖于POJO之间关系管理。依赖注入有两种,设值注入(IOC容器使用Setter方法注入依赖值)和构造注入(通过构造器注入)。
依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应用程序依赖容器创建并注入它所需要的外部资源;而控制反转是从容器的角度在描述,描述完整点:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。
好处:举个例子:
原始社会:需要斧子的人(调用者)只能自己去磨一把斧子(被调用者)。对应在Java中是,程序使用者自己创建被调用者,也就是使用new调用构造构造器创建爱你一个被调用者。这种情况有两个坏处,第一可扩展性差,人和斧子高度耦合,如果增加斧子的组建时,人的代码也需要改变;第二,职责混乱,人只需要调用斧子的方法即可,并不需要关系斧子的打磨的过程,人主动去创造斧子,职责混乱。
工业社会:斧子不再需要调用者自己去打磨,而是在工厂里创造,调用者只需要去工厂里拿斧子即可,无需关心斧子如何打磨,这就是工厂模式。虽然无需关心斧子的打磨过程,只需要找到对应的接口即可,也做到了调用者和被调用者的解耦,但是又和工厂耦合在一起。
共产主义社会:使用斧子的人无需找工厂,坐等社会提供。调用者无需关心被调用的实现,无需理会工厂,只需要等待Spring的依赖注入。这种情况是最理想的,程序完全无需要知道被调用者的创建过程,也无需要去定位工厂,做到了解耦。实例之间的依赖关系有IoC容器负责管理。
两种依赖注入方法的比较:
设值注入:1)与传统的JavaBean写法一样,程序员更容易理解,也更直观
2)对于过于复杂的依赖关系,如果使用构造注入,会导致构造器过于臃肿。而使用设值注入,则能避免这个问题。
3)在某些属性可选的情况下,多参数的构造器更笨重。
构造注入:1)构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖,优先注入。
2)对于依赖关系无需变化的Bean, 构造输入更方便,没有set方法,不会担心后续代码对依赖关系的破坏。
3)依赖关系只能在构造器中设定,则只有组建创造者才可以修改组建的依赖关系。组建的内部关系高度透明,符合高内聚原则。
建议一设值注入为主,构造注入为辅的构造策略。对依赖关系无需变化的注入,尽量使用构造注入,而其他依赖关系则尽量使用设值注入。