Spring 依赖注入(DI)

依赖注入简介

Dependency injection (DI) is a process whereby objects define their dependencies (that is, the other objects with which they work) only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse (hence the name, Inversion of Control) of the bean itself controlling the instantiation or location of its dependencies on its own by using direct construction of classes or the Service Locator pattern

上面官方文档的解释,以下大概描述一下:

依赖注入 (DI) 是一个过程,其中对象仅通过构造函数参数、工厂方法的参数或对象实例在构造或从工厂方法返回。 然后容器在创建 bean 时注入这些依赖项。 这个过程基本上是 bean 本身通过使用直接构造类或服务定位器模式来控制其依赖项的实例化或位置的逆过程(因此称为控制反转)

依赖注入的方式:

DI exists in two major variants: Constructor-based dependency injection and Setter-based dependency injection

 注:DI主要有两种注入方式,即基于构造器注入和基于Setter注入

构造器注入

基于构造器注入 DI通过调用带参数的构造器来实现,每个参数代表着一个依赖关系。此外,还可通过给 静态 工厂方法传参数来构造bean。接下来的介绍将认为给构造器传参数和给静态工厂方法传参数是类似的。

构造器参数解析

构造器参数通过参数类型进行匹配。如果构造器参数的类型定义没有潜在的歧义,那么bean被实例化的时候,bean定义中构造器参数的定义顺序就是这些参数的顺序并依次进行匹配。

举个例子:

在bean定义中指定的构造器参数会被用作ExampleBean的构造器参数。

使用构造器的例子,Spring调用静态工厂方法来返回对象的实例:

public class ExampleBean {

    // a private constructor
    private ExampleBean(...) {
        ...
    }

    // a static factory method; the arguments to this method can be
    // considered the dependencies of the bean that is returned,
    // regardless of how those arguments are actually used.
    public static ExampleBean createInstance (
        AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {

        ExampleBean eb = new ExampleBean (...);
        // some other operations...
        return eb;
    }

}
<bean id="exampleBean" class="examples.ExampleBean" factory-method="createInstance">
    <constructor-arg ref="anotherExampleBean"/>
    <constructor-arg ref="yetAnotherBean"/>
    <constructor-arg value="1"/>
</bean>

<bean id="anotherExampleBean" class="examples.AnotherBean"/>
<bean id="yetAnotherBean" class="examples.YetAnotherBean"/>

静态工厂方法参数由<constructor-arg/>元素提供,实际上这和使用构造器是一样的。工厂方法 返回的类的类型并不一定要与包含静态工厂方法的类类型一致,虽然在这个例子中是一样的。 实例工厂方法(不是静态的)与此相同(除了使用factory-bean属性代替class属性外),所以这里不作详细讨论。

Setter注入

Setter-based DI is accomplished by the container calling setter methods on your beans after invoking a no-argument constructor or a no-argument static factory method to instantiate your bean

在调用了无参的构造方法或者无参的静态工厂方法实例化bean之后,容器通过回调bean的setter方法来完成setter注入。

这里结合bean的生命周期更加容易理解:

通过构造器(无参构造)创建bean的实例 --> 为bean的属性设置值和其他的bean的引用(本质调用set方法)--> 调用bean的初始化方法 --> 获取bean对象(可以使用bean对象 )-->容器关闭调用bean的销毁方法

Setter注入例子使用基于XML的配置元数据的方式。相应的Spring XML配置文件:

<bean id="exampleBean" class="examples.ExampleBean">
    <!-- setter injection using the nested ref element -->
    <property name="beanOne">
        <ref bean="anotherExampleBean"/>
    </property>

    <!-- setter injection using the neater ref attribute -->
    <property name="beanTwo" ref="yetAnotherBean"/>
    <property name="integerProperty" value="1"/>
</bean>

<bean id="anotherExampleBean" class="examples.AnotherBean"/>
<bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
public class ExampleBean {

    private AnotherBean beanOne;
    private YetAnotherBean beanTwo;
    private int i;

    public void setBeanOne(AnotherBean beanOne) {
        this.beanOne = beanOne;
    }

    public void setBeanTwo(YetAnotherBean beanTwo) {
        this.beanTwo = beanTwo;
    }

    public void setIntegerProperty(int i) {
        this.i = i;
    }

}

构造器注入还是Setter注入?

混合使用构造器注入和setter注入, 强制性依赖关系 时使用构造器注入, 可选的依赖关系 时使用setter方法或者配置方法是比较好的经验法则。请注意@Required注解在setter方法上可以注入所需要的依赖。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值