利用dom4j简单模拟了一下spring是如何注入的,并用junit简单进行了一下测试。
定义一个BeanFactory接口,包含一个得到bean的方法
public interface BeanFactory {
Object getBean(String name);
}
定义一个ClassPathXmlApplicationContext类,利用dom4j解析bean.xml文件,用反射生成所需要的实例对象放入到beans容器中
package com.test.myspring;
import java.io.FileInputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class ClassPathXmlApplicationContext implements BeanFactory{
private Map<String,Object> beans = new HashMap<String,Object>();
@SuppressWarnings("rawtypes")
public ClassPathXmlApplicationContext(){
SAXReader reader = new SAXReader();
Document document;
try {
document = reader.read(new FileInputStream("bean.xml")); //得到xml文档,xml文件置于工程根目录下
Element root = document.getRootElement(); //得到根元素
for(Iterator i = root.elementIterator();i.hasNext();){
Element element = (Element)i.next();
String id = element.attributeValue("id"); //userDao
String clazz = element.attributeValue("class"); //com.test.myspring.UserDAOImpl
Object o = Class.forName(clazz).newInstance(); //生成UserDAOImpl的一个实例
beans.put(id, o);
for(Iterator ei = element.elementIterator();ei.hasNext();){ //遍历子元素
Element childe = (Element)ei.next();
String name = childe.attributeValue("name"); //本例中是得到userDao
String bean = childe.attributeValue("bean");
Object objectBean = beans.get(bean); //从beans容器中得到UserDAOImpl的实例
String methodName = "set"+name.substring(0, 1).toUpperCase()
+name.substring(1); //得到setUserDao方法名
Method method = o.getClass().getMethod(methodName,
objectBean.getClass().getInterfaces()[0]); //通过反射得到该方法
method.invoke(o, objectBean);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public Object getBean(String name) {
return beans.get(name);
}
}
bean.xml文件
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="userDao" class="com.test.myspring.UserDAOImpl"/> <bean id="userService" class="com.test.myspring.UserService"> <property name="userDao" bean="userDao"/> </bean> </beans>
另外有User、UserDAO、UserDAOImpl、UserService
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public interface UserDAO {
void add(User u);
}
public class UserDAOImpl implements UserDAO {
@Override
public void add(User u) {
System.out.println("A user has saved!");
}
}
public class UserService {
private UserDAO userDao;
public UserDAO getUserDao() {
return userDao;
}
public void setUserDao(UserDAO userDao) {
this.userDao = userDao;
}
public void add(User u){
this.userDao.add(u);
}
}
写一个简单的类UserServiceTest测试下
import org.junit.Test;
public class UserServiceTest {
@Test
public void testAdd(){
BeanFactory factory = new ClassPathXmlApplicationContext();
//首先直接得到了UserService的一个实例us
//然后通过ClassPathXmlApplicationContext中的第二个for循环自动装配了userDao
UserService us = (UserService)factory.getBean("userService");
User u = new User();
us.add(u);
}
}
运行输出A user has saved! 这里并没有真正去连接数据库。