关闭

深入解读Spring Framework IoC容器(第二弹:依赖注入的方式)

标签: springioc依赖注入构造器注入setter方法注入
393人阅读 评论(0) 收藏 举报
分类:

依赖注入 (DI) 是指定义对象之间的依赖关系的过程。容器的工作就是创建bean并注入依赖关系。这个过程来由容器来控制bean的实例或者其依赖关系,因此它有另外一个名字叫控制反转 (IoC)。

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

构造器注入

基于构造器注入DI通过调用带参数的构造器来实现,每个参数代表着一个依赖关系。

public class ExampleBean {

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

    public ExampleBean(
        AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {
        this.beanOne = anotherBean;
        this.beanTwo = yetAnotherBean;
        this.i = i;
    }

}
<bean id="exampleBean" class="examples.ExampleBean">
    <!-- 使用嵌套的ref元素 -->
    <constructor-arg>
        <ref bean="anotherExampleBean"/>
    </constructor-arg>

    <!-- 使用直接的ref属性 -->
    <constructor-arg ref="yetAnotherBean"/>

    <constructor-arg type="int" value="1"/>
</bean>

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

bean被实例化的时候,默认按bean定义中构造器参数的定义顺序依次进行匹配。

package x.y;

public class Foo {

    public Foo(Bar bar, Baz baz) {
        // ...
    }

}
<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>

可以使用type属性来显式指定简单类型的构造参数类型:

package examples;

public class ExampleBean {

    private int years;

    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属性来显式指定构造参数的索引:

<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>

不过这种方式需要使用@ConstructorProperties JDK注解明确指出构造函数的参数:

package examples;

public class ExampleBean {

    // 这里属性定义省略掉了

    @ConstructorProperties({"years", "ultimateAnswer"})
    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }

}

Setter注入

容器通过回调bean的setter方法来完成setter注入。

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;
    }

}
<bean id="exampleBean" class="examples.ExampleBean">
    <!-- 使用嵌套的ref元素 -->
    <property name="beanOne">
        <ref bean="anotherExampleBean"/>
    </property>

    <!-- 使用直接的ref属性 -->
    <property name="beanTwo" ref="yetAnotherBean"/>
    <property name="integerProperty" value="1"/>
</bean>

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

构造器注入和Setter注入如何选择

因为可以混合使用构造器注入和setter注入,强制性依赖关系时使用构造器注入,可选的依赖关系时使用setter方法注入是比较好的经验法则。

当实现的应用组件是不可变对象时使用构造器注入,构造器注入的组件总是返回给调用者完整的初始化状态。

setter注入主要用作可选的依赖,给这些依赖分配合理的缺省值。否则,当代码使用依赖时必须进行非空检查。setter注入的一个好处是setter方法使得这个类的对象在以后的某个时候还可合理的重新配置或者重新注入。

1
0
查看评论

spring技术内幕笔记:IoC容器的依赖注入

在IoC容器初始化的过程中,并没有看到IoC容器对Bean依赖关系的注入。假设IoC容器已经载入了Bean信息,依赖注入的过程是用户第一次向IoC容器索要Bean时触发的,当然也有例外,也就是通过lazy-init属性让容器完成Bean的预初始化。预初始化也是一个完成依赖注入的过程,只不过它是在初始...
  • lom9357bye
  • lom9357bye
  • 2017-07-17 22:03
  • 187

深入解读Spring Framework IoC容器(第三弹:依赖注入配置详解)

直接变量 元素的value值可以通过字符串形式来指定属性和构造器参数。 id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="clo...
  • lianjiww
  • lianjiww
  • 2017-01-05 00:05
  • 346

Spring学习(七)深入理解Spring IoC容器

IoC:他是Spring容器的内核,AOP、声明式事务等功能都依赖于此功能,它涉及代码解耦,设计模式、代码优化等问题的考量。
  • icarus_wang
  • icarus_wang
  • 2016-05-26 23:35
  • 981

Spring IOC源码详解之容器依赖注入

Spring IOC源码详解之容器依赖注入 上一篇博客中介绍了IOC容器的初始化,通过源码分析大致了解了IOC容器初始化的一些知识,先简单回顾下上篇的内容 载入bean定义文件的过程,这个过程是通过BeanDefinitionReader来完成的,其中通过 loadBea...
  • yujin753
  • yujin753
  • 2015-07-27 08:52
  • 2963

Spring Ioc容器依赖注入

Spring Ioc容器依赖注入
  • flykinghg
  • flykinghg
  • 2016-09-13 12:07
  • 18381

深入解读Spring Framework IoC容器(第六弹:Bean的作用域)

Bean作用域(scope)有如下种类: Scope Description singleton 这是默认的,每个Spring IoC容器中一个bean定义只对应一个实例。 prototype 一个bean定义对应多个实例。 request 一个bean定义作用于一个H...
  • lianjiww
  • lianjiww
  • 2017-01-05 22:59
  • 363

深入解读Spring Framework IoC容器(第五弹:懒加载)

懒加载也称延迟加载或延迟初始化。Spring默认在启动时将所有单例bean提前进行实例化,也就是说默认不是懒加载的。Ioc容器会把懒加载的bean在第一次需要的时候才实例化而不是在容器启动时就实例化。在XML配置文件中,懒加载通过<bean/>元素的lazy-init属性进行控制:<...
  • lianjiww
  • lianjiww
  • 2017-01-05 21:00
  • 665

深入浅出spring IOC中三种依赖注入方式

深入浅出spring IOC中三种依赖注入方式 spring的核心思想是IOC和AOP,IOC-控制反转,是一个重要的面向对象编程的法则来消减计算机程序的耦合问题,控制反转一般分为两种类型,依赖注入和依赖查找,依赖什么?为什么需要依赖?注入什么?控制什么?依赖注入和控制反转是一样的概念吗?接触...
  • u011637069
  • u011637069
  • 2016-07-19 19:53
  • 30430

Spring中依赖注入的两种方式的区别

1:Spring中依赖注入的两种方式:  (1):通过 setter 方法注入:                 其中,name属性的取值依...
  • StarskyBoy
  • StarskyBoy
  • 2016-08-22 11:44
  • 2712

spring 依赖注入的三种实现方式

一,什么是依赖注入? 让组件依赖于抽象,当组件要与其他实际对象发生依赖关系时,通过抽象来注入依赖的实际对象。 二,依赖注入的三种实现方式? 1.接口注入 2.set注入 3.构造注入 接口注入:指的就是在接口中定义要注入的信息,并通过接口完成注入。 关于实现接口注入的例子,步骤如下...
  • qq_34342083
  • qq_34342083
  • 2016-12-17 22:31
  • 978
    个人资料
    • 访问:74561次
    • 积分:2187
    • 等级:
    • 排名:千里之外
    • 原创:132篇
    • 转载:4篇
    • 译文:0篇
    • 评论:4条
    文章分类
    百度统计