所謂依賴注入就是指:在運行期,由外部容器動態地將依賴對象注入到組件中。
使用構造器注入
|
1
2
3
4
|
<constructor-arg index=“0” type=“java.lang.String” value=“xxx”/>//構造器注入
<bean id="xxx" class="daoimpl.PersonDaoImpl"></bean>
<constructor-arg index=“0” type=“java.lang.String” ref=“xxx”/>//構造器注入
|
PS:其中index的值代表構造器的第幾個參數,type代表屬性類型,value的值的類型為基本類型,ref的值為引用bean的名字。
范例:
配置文件:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?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-2.5.xsd">
<bean id="persondaoimpl" class="daoimpl.PersonDaoImpl"></bean>
<bean id="personService" class="zmc.PersonServicebean" >
<constructor-arg index="0" type="java.lang.String" value="zmcheng"></constructor-arg>
<constructor-arg index="1" type="dao.PersonDao" ref="persondaoimpl"></constructor-arg>
</bean>
</beans>
|
依賴對象類:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
package zmc;
import dao.PersonDao;
import zmcjk.PersonService;
public class PersonServicebean implements PersonService {
private String name;
private PersonDao personDao ;
public PersonServicebean(String name, PersonDao personDao) {
super();
this.name = name;
this.personDao = personDao;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public PersonDao getPersonDao() {
return personDao;
}
public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
}
public void save(){
System.out.println(this.name);
personDao.add();
}
}
|
使用屬性setter方法注入
基本類型對象注入:
|
1
2
3
|
<bean id="orderService" class="cn.itcast.service.OrderServiceBean">
<property name=“name” value=“zhao”/>
</bean>
|
示例:
配置文件:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?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-2.5.xsd">
<bean id="persondaoimpl" class="daoimpl.PersonDaoImpl"></bean>
<bean id="personService" class="zmc.PersonServicebean" >
<property name="name" value="zmc"></property>
<property name="age" value="88"></property>
<property name="persondao" ref="persondaoimpl"></property>
</bean>
</beans>
|
bean類:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
package zmc;
import dao.PersonDao;
import zmcjk.PersonService;
public class PersonServicebean implements PersonService {
private PersonDao persondao = null;
private String name=null;
private Integer age;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public PersonDao getPersondao() {
return persondao;
}
public void setPersondao(PersonDao persondao) {
this.persondao = persondao;
}
public void save(){
System.out.println(this.name);
System.out.println(this.age);
persondao.add();
}
}
|
注入其他bean:
方式一
|
1
2
3
4
|
<bean id="orderDao" class="cn.itcast.service.OrderDaoBean"/>
<bean id="orderService" class="cn.itcast.service.OrderServiceBean">
<property name="orderDao" ref="orderDao"/>
</bean>
|
PS:其中name為屬性名稱,ref是要注入bean的名稱
示例:
DAO層:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
package dao;
public interface PersonDao {
void add();
}
package daoimpl;
import dao.PersonDao;
public class PersonDaoImpl implements PersonDao {
public void add(){
System.out.println("執行dao的方法");
}
}
|
業務層:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package zmc;
import dao.PersonDao;
import zmcjk.PersonService;
public class PersonServicebean implements PersonService {
private PersonDao persondao = null;
public PersonDao getPersondao() {
return persondao;
}
public void setPersondao(PersonDao persondao) {
this.persondao = persondao;
}
public void save(){
persondao.add();
}
}
|
測試:
|
1
2
3
4
|
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService ps = (PersonService)ctx.getBean("personService");
ps.save();
ctx.close();
|
配置文件:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
<?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-2.5.xsd">
<bean id="persondaoimpl" class="daoimpl.PersonDaoImpl"></bean>
<bean id="personService" class="zmc.PersonServicebean" >
<property name="persondao" ref="persondaoimpl"></property>
</bean>
</beans>
|
測試結果:執行dao的方法
方式二(使用內部bean,但該bean不能被其他bean使用,不推薦)
|
1
2
3
4
5
|
<bean id="orderService" class="cn.itcast.service.OrderServiceBean">
<property name="orderDao">
<bean class="cn.itcast.service.OrderDaoBean"/>
</property>
</bean>
|
集合類型的裝配:
Spring可以對集合類型進行注入包括:Set集合,properties屬性集合,Map集合以及List集合。
注入方式如下:
配置文件:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<bean id="order" class="cn.itcast.service.OrderServiceBean">
<property name="lists">
<list>
<value>lihuoming</value>
<value>zmcheng</value>
</list>
</property>
<property name="sets">
<set>
<value>set1</value>
<value>set2</value>
</set>
</property>
<property name="maps">
<map>
<entry key="lihuoming" value="28"/>
<entry key="zmcheng" value="22"/>
</map>
</property>
<property name="properties">
<props>
<prop key="12">sss</prop>
<prop key="13">saa</prop>
</props>
</property>
</bean>
|
編碼模擬Spring使用屬性setter方法注入的原理:
簡單模擬的Spring容器:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
package zmcSpring;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
/*
* 簡單模擬Spring容器
*/
public class ZmcClassPathXMLApplicationContext {
private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();//保存bean的信息
private Map<String,Object> sigletons = new HashMap<String,Object>();//引用所有bean對象
public ZmcClassPathXMLApplicationContext(String fileName){
this.readXML(fileName);
this.instanceBeans();
this.injectObject();//依賴注入
}
/*
* 為bean屬性注入值
*/
private void injectObject() {
for(BeanDefinition beanDefinition : beanDefines){
Object bean = sigletons.get(beanDefinition.getId());//此時bean還沒有注入
//下面開始進行依賴注入
if(bean!=null){
//取得bean的屬性描述
try {
PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();//bean的屬性
for(PropertyDefinition propertyDefinition : beanDefinition.getProperty()){//用戶配置文件中定義的屬性
for(PropertyDescriptor properdesc : ps){
//判斷配置文件中屬性的名稱和bean中屬性的名稱是否相同
if(propertyDefinition.getName().equals(properdesc.getName())){
Method setter = properdesc.getWriteMethod();//獲得屬性的setter方法
if(setter!=null){
Object value = sigletons.get(propertyDefinition.getRef());
try {
setter.invoke(bean, value);
} catch (Exception e) {
e.printStackTrace();
} //把引用對象注入到屬性
}}}}}
catch(Exception e){
....
}
/*
* 完成bean的實例化
*/
private void instanceBeans(){
for(BeanDefinition beanDefinition : beanDefines){
try {
sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/*
* 讀取XMl配置文件
* @param filename
*/
public void readXML(String fileName){
SAXReader saxReader = new SAXReader();
Document document = null;
try{
URL xmlpath = this.getClass().getClassLoader().getResource(fileName);
document = saxReader.read(xmlpath);
Map<String,String> nsMap = new HashMap<String,String>();
nsMap.put("ns", "http://www.springframework.org/schema/beans");//加入命名空間
XPath xsub = document.createXPath("//ns:beans/ns:bean");//創建beans/bean查詢路徑
xsub.setNamespaceURIs(nsMap);//設置命名空間
List<Element> beans = xsub.selectNodes(document);
for(Element element : beans){
String id = element.attributeValue("id");
String clazz = element.attributeValue("class");
BeanDefinition beanDefinition = new BeanDefinition(id,clazz);
XPath propertysub = element.createXPath("ns:property");//nodename(節點名稱):表示選擇該節點的所有子節點
propertysub.setNamespaceURIs(nsMap);
List<Element> propertys = propertysub.selectNodes(element);
for(Element property:propertys){
String propertyName = property.attributeValue("name");
String propertyRef = property.attributeValue("ref");
PropertyDefinition pd = new PropertyDefinition(propertyName, propertyRef);
beanDefinition.getProperty().add(pd);
}
beanDefines.add(beanDefinition);
}
}
catch (Exception e){
e.printStackTrace();
}
}
/*
*獲取bean實例
*/
public Object getBean(String beanName){
return this.sigletons.get(beanName);
}
}
|
Bean屬性信息:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
package zmcSpring;
import java.util.ArrayList;
import java.util.List;
public class BeanDefinition {
private String id;
private String className;
private List<PropertyDefinition> property = new ArrayList<PropertyDefinition>();
public List<PropertyDefinition> getProperty() {
return property;
}
public void setProperty(List<PropertyDefinition> property) {
this.property = property;
}
public BeanDefinition() {
super();
}
public BeanDefinition(String id, String className) {
super();
this.id = id;
this.className = className;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
}
|
Property信息:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
package zmcSpring;
public class PropertyDefinition {
public PropertyDefinition(String name, String ref) {
super();
this.name = name;
this.ref = ref;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
private String name;
private String ref;
}
|
測試類:
|
1
2
3
4
5
6
7
8
|
@Test
public void T() {
ZmcClassPathXMLApplicationContext zmc = new ZmcClassPathXMLApplicationContext("beans.xml");
PersonService ps = (PersonService)zmc.getBean("personService");
ps.save();
}
|
