简单的理解Spring的实现过程,模拟了Spring的读取配置文件
项目结构
主要代码如下
User.java
1
2
3
4
5
6
|
public class User {
private String username;
private String password;
// getter and setter ..
} |
beans.xml 配置文件
1
2
3
4
5
6
|
<beans> <bean id= "u" class = "com.demo.dao.impl.UserDAOImpl" />
<bean id= "userService" class = "com.demo.service.UserService" >
<property name= "userDAO" bean= "u" />
</bean>
</beans> |
ClassPathXmlApplicationContext.java
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
|
/** * 管理器
*
* @author jerome_s@qq.com
*/
public class ClassPathXmlApplicationContext implements BeanFactory {
private Map<String, Object> beans = new HashMap<String, Object>();
/**
* 初始化配置文件
* 模拟spring配置文件。模拟大的工厂,把东西都写到大的配置文件,通过代码读取xml文件模拟spring。
*
* @throws Exception
*/
@SuppressWarnings ( "unchecked" )
public ClassPathXmlApplicationContext() throws Exception {
System.out.println( "ClassPathXmlApplicationContext init." );
SAXBuilder sb = new SAXBuilder();
Document doc = sb.build( this .getClass().getClassLoader().getResourceAsStream( "beans.xml" )); // 构造文档对象
Element root = doc.getRootElement(); // 获取根元素HD
List<Element> list = root.getChildren( "bean" ); // 取名字为bean的所有元素
// 循环每个bean
for ( int i = 0 ; i < list.size(); i++) {
Element element = list.get(i);
String id = element.getAttributeValue( "id" );
String clazz = element.getAttributeValue( "class" );
Object o = Class.forName(clazz).newInstance();
System.out.println( "ClassPathXmlApplicationContext bean's id = " + id);
System.out.println( "ClassPathXmlApplicationContext bean's class = " + clazz);
beans.put(id, o);
// 循环bean下的property
for (Element propertyElement : (List<Element>) element.getChildren( "property" )) {
// 调用 setUserDAO 设置 userDao的值
String name = propertyElement.getAttributeValue( "name" ); // userDAO
String bean = propertyElement.getAttributeValue( "bean" ); // u
System.out.println( "ClassPathXmlApplicationContext bean's property name = " + name);
System.out.println( "ClassPathXmlApplicationContext bean's property bean = " + bean);
Object beanObject = beans.get(bean); // UserDAOImpl instance
// userDAO -> setUserDao
String methodName = "set" + name.substring( 0 , 1 ).toUpperCase() + name.substring( 1 );
Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[ 0 ]);
m.invoke(o, beanObject);
System.out.println( "ClassPathXmlApplicationContext bean's property invoke method " + methodName);
}
System.out.println( "-------------------------" );
}
}
public Object getBean(String id) {
return beans.get(id);
}
} |
UserService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class UserService {
private UserDAO userDAO;
public void add(User user) {
userDAO.save(user);
}
public UserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(UserDAO userDAO) {
this .userDAO = userDAO;
}
} |
UserDAOImpl.java
1
2
3
4
5
6
7
8
|
public class UserDAOImpl implements UserDAO {
public void save(User user) {
System.out.println( "UserDAOImpl saved()" );
System.out.println( "user.toString() = " + user.toString());
}
} |
运行结果如下
ClassPathXmlApplicationContext init.
ClassPathXmlApplicationContext bean's id = u
ClassPathXmlApplicationContext bean's class = com.demo.dao.impl.UserDAOImpl
-------------------------
ClassPathXmlApplicationContext bean's id = userService
ClassPathXmlApplicationContext bean's class = com.demo.service.UserService
ClassPathXmlApplicationContext bean's property name = userDAO
ClassPathXmlApplicationContext bean's property bean = u
ClassPathXmlApplicationContext bean's property invoke method name = setUserDAO
-------------------------
UserDAOImpl saved()
user.toString() = User [username=jerome, password=jeromepwd]
源码