Spring的核心技术(五)---基于构造器的依赖注入

基于构造器的依赖注入

基于构造器的依赖注入(DI)是通过调用带有代表依赖参数的构造器来实现的。调用带有指定给Bean构造器的参数的静态工厂方法也是相似的,并且有关把给构造器和静态工厂方法传递参数的讨论也是类似的。下面的示例展示了使用构造器来注入依赖的类。注意这个 类没有特殊的依赖,它只是一个不依赖于容器特定接口、基类或注解的POJO对象。

public class SimpleMovieLister {
 
    // the SimpleMovieLister has a dependency on a MovieFinder
    private MovieFinder movieFinder;
 
    // a constructor so that the Spring container can inject a MovieFinder
    public SimpleMovieLister(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
 
    // business logic that actually uses the injected MovieFinder is omitted...
 
}

构造器参数的解析

构造器参数的解析时通过相关参数的类型来匹配的。如果Bean定义的构造器中的参数对象不存在,那么Bean定义中的构造器的参数的顺序就是在示例化Bean的时候提供给对应构造器的参数的顺序,例如:

package x.y;
 
public class Foo {
 
    public Foo(Bar bar, Baz baz) {
        // ...
    }
 
}

如果构造器参数bar和baz不存在,并且假设Bar类和Baz类没有相关的继承,这样下面的配置就可以很好的工作,并且不需要再<constructor-arg/>元素中明确的指定构造器参数的索引或/和类型。

<beans>
    <bean id="foo" class="x.y.Foo">
        <constructor-arg ref="bar"/>
        <constructor-arg ref="baz"/>
    </bean>
 
    <bean id="bar" class="x.y.Bar"/>
 
    <bean id="baz" class="x.y.Baz"/>
</beans>

在引用其他的Bean的时候,类型是已知的,并且匹配能够发生(像上述的示例那样)。当使用简单的类型时,如<value>true</value>,Spring不能够判断值的类型,在没有帮助的情况下不能匹配到正确的类型,因此要像下面的示例那样使用type属性来指定值的类型。

package examples;
 
public class ExampleBean {
 
    // Number of years to calculate the Ultimate Answer
    private int years;
 
    // The Answer to Life, the Universe, and Everything
    private String ultimateAnswer;
 
    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
 
}

 

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg type="int" value="7500000"/>
    <constructor-arg type="java.lang.String" value="42"/>
</bean>

使用index属性来明确的指定构造器参数的索引,这样就可以解决带有多个相同简单类型参数的所引入的歧义性。注意:索引是从0开始的。例如:

<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才能够查找来自构造器的参数名称。如果不想在可调式模式来编译,可以使用JDK的@ConstructorProperties注解来明确构造器参数的名称,例如:

package examples;
 
public class ExampleBean {
 
    // Fields omitted
 
    @ConstructorProperties({"years", "ultimateAnswer"})
    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
 
}

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页