基于构造器的注入方式
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.
Spring v3.0.2 Learning Note 7 - Constructor-based dependency injection
最新推荐文章于 2023-11-29 15:35:44 发布