4-1基于构造函数的依赖注入

基于构造函数的依赖注入

基于构造函数的DI是通过容器调用具有多个参数(每个参数代表一个依赖项)的构造函数来完成的。 调用带有特定参数的静态工厂方法来构造Bean几乎是等效的,并且本次讨论将构造函数和静态工厂方法的参数视为类似。

以下示例显示了只能通过构造函数注入进行依赖项注入的类:

public class SimpleMovieLister {

    // SimpleMovieLister依赖于MovieFinder
    private final MovieFinder movieFinder;

    // 构造函数,以便Spring容器可以注入MovieFinder
    public SimpleMovieLister(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // 实际使用注入的MovieFinder的业务逻辑被省略...
}
构造函数参数解析

构造函数参数解析匹配是通过使用参数的类型进行的。 如果Bean定义的构造函数参数中没有潜在的歧义,则在实例化Bean时,在Bean定义中定义构造函数参数的顺序就是将这些参数提供给适当的构造函数的顺序。

考虑以下类别:

package x.y;

public class ThingOne {

    public ThingOne(ThingTwo thingTwo, ThingThree thingThree) {
        // ...
    }
}

假设ThingTwo和ThingThree类没有通过继承关联,则不存在潜在的歧义。 因此,以下配置可以正常工作,并且您无需在元素中显式指定构造函数参数索引或类型。

<beans>
    <bean id="beanOne" class="x.y.ThingOne">
        <constructor-arg ref="beanTwo"/>
        <constructor-arg ref="beanThree"/>
    </bean>

    <bean id="beanTwo" class="x.y.ThingTwo"/>

    <bean id="beanThree" class="x.y.ThingThree"/>
</beans>

当引用另一个bean时,类型是已知的,并且可以发生匹配(与前面的示例一样)。 当使用简单类型(例如 true </ value>)时,Spring无法确定值的类型,因此在没有帮助的情况下无法按类型进行匹配。

考虑以下类别:

package examples;

public class ExampleBean {

    // 计算最终答案的年数
    private final int years;

    // 生命,宇宙和一切的答案
    private final String ultimateAnswer;

    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
}
构造函数参数类型匹配

在上述情况下,如果通过使用type属性显式指定构造函数参数的类型,则容器可以使用简单类型的类型匹配,如以下示例所示:

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg type="int" value="7500000"/>
    <constructor-arg type="java.lang.String" value="42"/>
</bean>
构造函数参数索引

您可以使用index属性来显式指定构造函数参数的索引,如以下示例所示:

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg index="0" value="7500000"/>
    <constructor-arg index="1" value="42"/>
</bean>

除了解决多个简单值的歧义性之外,指定索引还可以解决歧义,其中构造函数具有两个相同类型的参数。

构造函数参数名称

您还可以使用构造函数参数名称来消除歧义,如以下示例所示:

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg name="years" value="7500000"/>
    <constructor-arg name="ultimateAnswer" value="42"/>
</bean>

请记住,要立即使用该功能,必须在启用调试标志的情况下编译代码,以便Spring可以从构造函数中查找参数名称。 如果您不能或不想使用debug标志编译代码,则可以使用**@ConstructorProperties** JDK注释显式命名构造函数参数。 然后,样本类必须如下所示:

package examples;

public class ExampleBean {

    // 字段省略

    @ConstructorProperties({"years", "ultimateAnswer"})
    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值