Spring v3.0.2 Learning Note 7 - Constructor-based dependency injection

本文详细介绍了Spring框架中基于构造器的依赖注入方式,并通过具体的Java代码示例展示了如何进行构造器注入及其配置方法。

基于构造器的注入方式

package com.spring.test.dao;

public class PersonDao {

    public void add() {
        System.out.println("This is add() method in DAO layer.");
    }
}
--------------------------------------------------------------------------
package com.spring.test.manager.impl;

import com.spring.test.dao.PersonDao;
import com.spring.test.manager.IPersonService;

public class PersonManager implements IPersonService {

    private PersonDao personDao;
    private String name;

    public PersonManager() {
    }

    public PersonManager(PersonDao personDao, String name) {
        super();
        this.personDao = personDao;
        this.name = name;
    }

    @Override
    public void save() {
        personDao.add();
        System.out.println("name is " + name);
    }

}

该类的构造函数有2个属性,一个是类PersonDao,一个是String类型的变量。spring关于构造器注入的配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="personDao" class="com.spring.test.dao.PersonDao" />
    <bean id="personService" class="com.spring.test.manager.impl.PersonManager">
        <constructor-arg index="0" type="com.spring.test.dao.PersonDao"
            ref="personDao" />
        <constructor-arg index="1" type="java.lang.String"
            value="name string" />
    </bean>
</beans>
这是关于constructor-arg的设置,其作用就是通过构造器注入依赖的对象或基本数据类型的值。
 index从0开始计数,其顺序要与类中的参数一一对应。

测试类:
package com.spring.test.junit;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.spring.test.manager.IPersonService;

public class PersonServiceTest {

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
    }

    @Test
    public void test() {
        AbstractApplicationContext ctx = new ClassPathXmlApplicationContext(
                "spring.xml");
        IPersonService personService = (IPersonService) ctx
                .getBean("personService");
        personService.save();
    }

}
运行该测试类,可看到正确的注入结果。

基于构造器的注入还是基于Setter方式的注入?
推荐采用Setter的注入方式,以下内容来自spring的参考文档

Constructor-based or setter-based DI?

Since you can mix both, Constructor- and Setter-based DI, it is a good rule of thumb to use constructor arguments for mandatory dependencies and setters for optional dependencies. Note that the use of a @Required annotation on a setter can be used to make setters required dependencies.
The Spring team generally advocates setter injection , because large numbers of constructor arguments can get unwieldy, especially when properties are optional. Setter methods also make objects of that class amenable to reconfiguration or re-injection later. Management through JMX MBeans is a compelling use case.
Some purists favor constructor-based injection. Supplying all object dependencies means that the object is always returned to client (calling) code in a totally initialized state. The disadvantage is that the object becomes less amenable to reconfiguration and re-injection.
Use the DI that makes the most sense for a particular class. Sometimes, when dealing with third-party classes to which you do not have the source, the choice is made for you. A legacy class may not expose any setter methods, and so constructor injection is the only available DI.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值