通过读取xml文件,利用反射动态加载类和方法,其实就是spring的注入机制
模拟,可以清晰的看出整个运行流程
1、配置文件 applicationContext.xml
<beans> <bean id="sd" class="dao.impl.IStudentDaoImpl"/> <bean id="studentService" class="service.StudentService"> <property name="studentDao" ref="sd"/> </bean> </beans>
property标签中name 为 StudentService.java的属性
2、dao
package dao; public interface StudentDao { public void save(); }
3、daoImpl
1)
package dao.impl; import dao.StudentDao;public class IStudentDaoImpl implements StudentDao { public void save() { System.out.println("IStudentDaoImpl.save()"); } }
2)
package dao.impl; import dao.StudentDao; public class StudentDaoImpl implements StudentDao{ public void save() { System.out.println("StudentDaoImpl.save()"); } }
4、service
package service; import dao.StudentDao; public class StudentService { private StudentDao studentDao; public StudentDao getStudentDao() { return studentDao; } public void setStudentDao(StudentDao studentDao) { this.studentDao = studentDao; } public void save(){ this.studentDao.save(); } }
5、解析xml文件
package util; import java.lang.reflect.Method; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.input.SAXBuilder; public class ClassPathXmlApplicationContext { static Map<String,Object> map=new HashMap<String,Object>(); public void SaxXml() throws Exception{ SAXBuilder sb=new SAXBuilder(); Document doc=sb.build(this.getClass().getClassLoader().getResourceAsStream("applicationContext.xml")); Element root=doc.getRootElement(); List<Element> list=root.getChildren("bean"); for(int i=0;i<list.size();i++){ Element ele=list.get(i); String id=ele.getAttributeValue("id"); String obj=ele.getAttributeValue("class"); Object o=Class.forName(obj).newInstance(); map.put(id, o); for(Element elePro:(List<Element>)ele.getChildren("property")){ String name=elePro.getAttributeValue("name"); String bean=elePro.getAttributeValue("ref"); String methodName="set"+name.substring(0, 1).toUpperCase()+name.substring(1); System.out.println("MethodName:"+methodName); Method m=o.getClass().getMethod(methodName, map.get(bean).getClass().getInterfaces()[0]); m.invoke(o, map.get(bean)); } } } public static Object get(String id){ return map.get(id); } }
6、创建测试类
package service; import static org.junit.Assert.*; import org.junit.Test; import util.ClassPathXmlApplicationContext; public class StudentServiceTest { @Test public void testSave() throws Exception { ClassPathXmlApplicationContext cpac=new ClassPathXmlApplicationContext(); cpac.SaxXml(); StudentService ss=(StudentService)ClassPathXmlApplicationContext.get("studentService"); ss.save(); } }
输出结果:IStudentDaoImpl.save() ,因为在xml文件中配置的是IStudentDaoImpl 没有配置StudentDaoImpl,所以反射加载的只是IStudentImpl