利用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! 这里并没有真正去连接数据库。