使用JDom解析XML文档模拟Spring的配置文件解析
在J2EE项目中可能会涉及到一些框架的使用,最近接触到了SSH,拿Spring来说配置文件的使用是相当重要的,Spring的配置文件是一个xml文件,Spring是如何读取到配置文件并进行依赖注入的呢?今天先来说说xml文件的解析。
解析xml文件可以使用jdom,下面我以一个小栗子来说说xml文件的解析。
1.首先下载jdom,在这里我以jdom2.0.6为例
2.接下来附上一个xml文档
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="u" class="edu.nupt.bbs.UserDAOImp" /> <bean id ="service" class="edu.nupt.bbs.UserService"> <property name="userdao" ref="u" /> </beans> </beans>
代码模仿的是Spring的配置文件
3.定义一个User类(model)代码如下
package edu.nupt.bbs; public class User { private String id; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } private String name; }
4.定义一个UserDAO接口这是一个DAO接口为了方便实验主要提供了addUser和deleteUser接口
package edu.nupt.bbs; public interface UserDAO { public void add(); public void delete(); }
5.定义一个UserDAOImp实现了UserDAO接口一开始我不太明白为什么要将UserDAO写成接口的形式可能是为了在不同的数据库上面做到兼容,具体的代码如下,为了简单直观在add方法和delete方法中直接在控制台打印出一段文字
package edu.nupt.bbs; /** * 一种UserDAO的实现(在实际的应用中可能是一种数据库对应一种UserDAO实现) * @author xiaoysec * */ public class UserDAOImp implements UserDAO { @Override public void add() { // TODO Auto-generated method stub System.out.println("user add"); } @Override public void delete() { // TODO Auto-generated method stub System.out.println("user delete"); } }
6.定义UserService类实现User对象的增删,一开始接触J2EE的时候不是很清楚为什么要写这么多看似不需要的类,但是渐渐地会发现这种分层的思想是极为合理的,方便了程序的拓展和维护。
package edu.nupt.bbs; /** * 一种UserDAO的实现(在实际的应用中可能是一种数据库对应一种UserDAO实现) * @author xiaoysec * */ public class UserDAOImp implements UserDAO { @Override public void add() { // TODO Auto-generated method stub System.out.println("user add"); } @Override public void delete() { // TODO Auto-generated method stub System.out.println("user delete"); } }
基本的工作已经结束了,下面就是进行Spring配置文件读取的模拟了,我模仿了Spring中的命名方式定义了:BeanFactory和ClassPathXmlApplicationContext
7.BeanFactory接口 返回的是一个Object对象我们通过xml的id属性作为参数从BeanFactory中取出一个Bean对象。这个接口就像他的名字一样可以把她想象成一个工厂通过id参数为外界提供bean对象。
package edu.nupt.bbs.Spring; //根据id返回一个bean public interface BeanFactory { public Object getBean(String id); }
8.ClassPathXmlApplicationContext
package edu.nupt.bbs.Spring; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.input.SAXBuilder; import org.junit.Test; import edu.nupt.bbs.test.JdomTest; public class ClassPathXmlApplicationContext implements BeanFactory { // 用于存放bean实例对象 private Map<String, Object> map = new HashMap<String, Object>(); // 用于取出bean实例对象 @Override public Object getBean(String id) { // TODO Auto-generated method stub Object o = map.get(id); return o; } public ClassPathXmlApplicationContext() { try { SAXBuilder sb = new SAXBuilder(); Document doc = sb.build(JdomTest.class.getClassLoader() .getResourceAsStream("jdom.xml")); // 构造文档对象 Element root = doc.getRootElement(); // 获取根元素 beans List list = root.getChildren("bean");// 取名字为bean的所有元素 for (int i = 0; i < list.size(); i++) { Element element = (Element) list.get(i); String id = element.getAttributeValue("id"); // 获取id的值 String clazz = element.getAttributeValue("class");// 获取class的值 // System.out.println(id + ":" + clazz); try { Object o = Class.forName(clazz).newInstance(); map.put(id, o);// 将id代表的对象放入map } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } catch (JDOMException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
需要提供一个Map对象作为容器存放生成的bean对象,其实上面的代码就是完成了xml解析以及bean实例对象的生成,并把bean实例对象放在map中,其中用到了Java反射。
<bean id="u" class="edu.nupt.bbs.UserDAOImp" />这是上面代码中存放在List的一个对象,其实就是用反射根据class的值生成实例的对象赋值给u即 UserDAOImp u = new UserDAOImp();
9.测试类
package edu.nupt.bbs.test; import static org.junit.Assert.*; import org.junit.Test; import edu.nupt.bbs.User; import edu.nupt.bbs.UserDAO; import edu.nupt.bbs.UserService; import edu.nupt.bbs.Spring.BeanFactory; import edu.nupt.bbs.Spring.ClassPathXmlApplicationContext; public class UserServiceTest { @Test public void addUsertest() { BeanFactory bf = new ClassPathXmlApplicationContext(); UserDAO userdao = (UserDAO)bf.getBean("u"); UserService service = (UserService)bf.getBean("service"); service.setUserdao(userdao); service.addUser(); } }
测试结果