注入bean有两种方式:
1
2
3
4
5
6
7
8
9
10
11
12 |
注入其他bean: 方式一 <bean id= "orderDao"
class = "cn.itcast.service.OrderDaoBean" /> <bean id= "orderService"
class = "cn.itcast.service.OrderServiceBean" > <property name= "orderDao"
ref = "orderDao" /> </bean> 方式二(使用内部bean,但该bean不能被其他bean使用) <bean id= "orderService"
class = "cn.itcast.service.OrderServiceBean" > <property name= "orderDao" > <bean class = "cn.itcast.service.OrderDaoBean" /> </property> </bean> |
一般我们的工程在service层依赖dao层的实现来实现业务逻辑。
service层:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 |
public
class PersonServiceImpl implements PersonService { private
PersonDao personDao; @Override public
void save() { personDao.save(); System. out .println( "service : "
+ " save 方法" ); } public
PersonDao getPersonDao() { return
personDao; } public
void setPersonDao(PersonDao personDao) { this .personDao = personDao; } } |
dao层:
1
2
3
4
5
6 |
public
class PersonDaoImpl implements PersonDao { @Override public
void save() { System. out .println( "dao层的save方法" ); } } |
beans.xml的配置
1
2
3
4
5
6
7
8
9
10
11 |
<?xml version= "1.0"
encoding= "UTF-8" ?> <beans xmlns= "http://www.springframework.org/schema/beans" xsi:schemaLocation="http: //www.springframework.org/schema/beans http: //www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id= "personDaoImpl"
class = "cn.gbx.dao.PersonDaoImpl" ></bean> <bean id= "personServiceImpl"
class = "cn.gbx.serviceimpl.PersonServiceImpl"
> <property name= "personDao"
ref = "personDaoImpl" ></property> </bean> </beans> |
测试方法:
1
2
3
4
5
6
7
8 |
public
class SpringTest { @Test public
void spring1() { ApplicationContext ctx = new
ClassPathXmlApplicationContext( "beans.xml" ); PersonService ps = (PersonService)ctx.getBean( "personServiceImpl" ); ps.save(); } } |
然后我们就实现了Spring对bean对象的依赖注入。 service层所依赖的dao层的PersonDao对象不是由service本身去创建管理,而是交给了第三方容器Spring去管理。
那么Spring是如何管理的呢?
我们可想而知
1: 首先必须解析XML 将 <bean>标签和 <property>标签都解析出来
2: 利用反射实例话对象
3: 利用内省将实例化完成的对象注入到有依赖的对象里面
我们可以自己模拟实现:
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135 |
package cn.gbx.myExample; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; 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.DocumentException; import org.dom4j.Element; import org.dom4j.XPath; import org.dom4j.io.SAXReader; public
class MyClassPathXmlApplicationContext { private
List<DefBean> defBeans = new
ArrayList<DefBean>(); //存储<bean>标签的信息 private
Map<String, Object> singltons = new
HashMap<String, Object>(); //存储读出来的对象 public
MyClassPathXmlApplicationContext() { super(); } public
MyClassPathXmlApplicationContext(String filename) { this .readXML(filename); this .instanceBean(); this .injectProperty(); } //利用内省将属性注入 private
void injectProperty() { for
(DefBean defBean : defBeans) { Object bean = singltons. get (defBean.getId()); if
(bean != null ) { //要想将依赖的对象注入,我们就要通过内省来操作对象的属性 try
{ BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass()); PropertyDescriptor[] ps = beanInfo.getPropertyDescriptors(); for
(DefProperty p : defBean.getDefPropertys()) { for
(PropertyDescriptor propertyDes : ps) { if
(propertyDes.getName(). equals (p.getName())) { Method setter = propertyDes.getWriteMethod(); if
(setter != null ) { Object value = singltons. get (p.getRef()); setter.setAccessible( true ); //这样即使set方法是私有的都可以访问 setter.invoke(bean, value); //把引用对象注入到bean属性里面 } break ; } } } } catch
(Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } //利用反射实例化对象 private
void instanceBean() { for
(DefBean bean : defBeans) { //输出测试读取的xml /*System.out.println(bean.getId() + " : " + bean.getClassName()); System.out.println("------------------------"); for (DefProperty p : bean.getDefPropertys()) { System.out.println("Property : name = " + p.getName() + " : ref = " + p.getRef()); } */ if
(bean.getClassName() != null
&& ! "" . equals (bean.getClassName())) { try
{ singltons.put(bean.getId(), Class.forName(bean.getClassName()).newInstance()); } catch
(Exception e) { e.printStackTrace(); } } } } private
void readXML(String filename) { SAXReader reader = new
SAXReader(); Document document = null ; URL xmlPath = this .getClass().getClassLoader().getResource(filename); try
{ document = reader.read(xmlPath); //创建命名空间 Map<String, String> nsMap = new
HashMap<String, String>(); //创建查询路径 XPath xsub = document.createXPath( "//ns:beans/ns:bean" ); xsub.setNamespaceURIs(nsMap); // 设置命名空间 List<Element> elements = xsub.selectNodes(document); DefBean defBean = null ; for
(Element e : elements) { String id = e.attributeValue( "id" ); String className = e.attributeValue( "class" ); defBean = new
DefBean(id, className); //为<bean>节点设置查询路径 XPath xPropertySub = e.createXPath( "ns:property" ); xPropertySub.setNamespaceURIs(nsMap); List<Element> propertys = xPropertySub.selectNodes(e); DefProperty defProperty = null ; for
(Element e2 : propertys) { String name = e2.attributeValue( "name" ); String ref
= e2.attributeValue( "ref" ); defProperty = new
DefProperty(name, ref ); defBean.getDefPropertys().add(defProperty); } defBeans.add(defBean); } } catch
(Exception e) { e.printStackTrace(); } } public
Object getBean(String key) { return
singltons. get (key); } } |
原文:http://www.cnblogs.com/E-star/p/3558346.html