基於構造器的注入方式
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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.