1. Spring核心机制:依赖注入

1.1 依赖注入

        应用中大量存在A对象需要调用B对象方法的情形,这种情形被称为依赖,即A对象依赖B对象。

        通常有如下两种方式来实现依赖:

        (1)原始做法:调用者主动创建被依赖对象,然后再调用被依赖对象的方法;

        (2)简单工厂模式:调用者先找到被依赖对象的工厂,然后主动通过工厂去获取被依赖对象,最后再调用被依赖对象的方法。(此方试遵守如下原则:①调用者面向被依赖对象的接口编程;②将被依赖对象的创建交给工厂完成;③调用者通过工厂来获得被依赖组件。)

        两种注入方式的弊端:

        原始做法:调用者主动创建对象,导致调用者与被依赖对象实现类的硬编码耦合,不利于项目升级和维护。

        简单工厂模式:调用组件需要主动通过工厂去获取被依赖对象,这就会带来调用组件与被依赖对象工厂的耦合。

        Spring方式实现依赖:

        程序无须使用new关键字调用构造器去创建对象,所有的Java对象都可交给Spring容器去创建;当调用者需要调用被依赖对象的方法时,调用者无须主动获取被依赖对象,只要等待Spring容器注入即可。

        综上所述,Spring实现依赖的方式,弥补了前两种方式实现依赖所存在的不足。

        使用Spring框架之后,调用者获取被依赖对象的方式由原来的主动获取,变成了被动接受,这种方式被称为控制反转(Inversion of Control,IoC)。从Spring容器的角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量——相当于为调用者注入他所依赖的实例,因此这种方式又被称为依赖注入(Dependency Injection,DI)

1.2 Spring依赖注入

        Spring框架的核心机制有两个:

        (1)Spring容器作为超级大工厂,负责创建、管理所有的Java对象,这些Java对象被称为Bean;

        (2)Spring容器管理容器中Bean之间的依赖关系,Spring使用一种被称为“依赖注入”的方式来管理Bean之间的依赖关系。

        Spring使用配置文件或注解配置Bean,在配置文件中,Spring配置Bean实例通常制定如下属性:

        id:指定该Bean唯一的表示,Spring根据id属性值来管理Bean,程序通过id属性值来访问该Bean实例;

        class:指定该Bean的实现类,此处不可用接口,必须使用实现类,Spring容器会使用XML解析器读取该属性值,并利用反射来创建该实现类的实例。

        Spring依赖注入的两种方式:

        (1)设值注入:IoC容器使用成员变量的setter方法来注入被依赖对象;

        (2)构造注入:IoC容器使用构造器来注入被依赖对象。

1.2.1 设值注入

        Bean与Bean之间的依赖关系由Spring管理,Spring采用setter方法为目标Bean注入所依赖的Bean,这种方式被称为设值注入。

1.2.2 构造注入

        Bean与Bean之间的依赖关系由Spring管理,Spring在构造实例时,同时为其完成了依赖关系的初始化。这种利用构造器来设置依赖关系的方式,被称为构造注入。

1.3 两种注入方式的对比

        两种注入方式没有绝对的好坏,只是适应的场景有所不同。

        设值注入具有如下优势:

        (1)与传统的JavaBean的写法更相似,程序开发人员更容易理解、接受。通过setter方法设定依赖关系显得更加直观、自然;

        (2)对于复杂的依赖关系,如果采用构造注入,会导致构造器过于臃肿,难以阅读。Spring在创建Bean实例时,需要同时实例化其依赖的全部实例,因而导致性能下降。而使用设值注入,则能避免这些问题。

        (3)尤其是在某些成员变量可选的情况下,多参数的构造器更加笨重。

        构造注入具有如下优势:

        (1)构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入。

        (2)对于依赖关系无须变化的Bean,构造注入更有用处。因为没有setter方法,所有的依赖关系全部在构造器内设定。因此,无须担心后续的代码对依赖关系产生破坏。

        (3)依赖关系只能在构造器内设定,则只有组件的创建者才能改变组件的依赖关系。对组件的调用者而言,组件内部的依赖关系完全透明,更符合高内聚的原则。

        因此,建议采用一设值注入为主,构造注入为辅的注入策略。

你可能感兴趣的:(1. Spring核心机制:依赖注入)