最近,看spring,觉得spring的一些源码,很牛就来模仿下,模仿的目的不是为了炫耀啥,只是提高自己的编码质量。
要模仿ClassPathXmlApplicationContext类的实现,首先要读取spring中applicationContext.xml的内容,同时还要生成类的实例,自然用到的技术就有 dom4j的操作、再就是java 的反射机制、路径操作。
为了测试我在applicationContext.xml中添加了一个bean。
1、applicationContext.xml文件的内容如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="person" class="com.cvicse.service.impl.PersonServiceImpl" /> </beans>
2、为了存取bean的信息,我们定义一个definebean的pojo类
package com.cvicse.bean; /** * * @功能:存储bean的pojo类 * @创建人 gao_jie * @创建日期 Jun 16, 2009 * @版本 1.0 * */ public class DefineBean { private String id; private String className; public DefineBean(String id, String className) { this.id = id; this.className = className; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } }
3、实现ClassPathXmlApplicationContext类
package com.cvicse.util; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.XPath; import org.dom4j.io.SAXReader; import com.cvicse.bean.DefineBean; /** * * @功能 ClassPathApplicationContext类 * @创建人 gao_jie * @创建日期 Jun 16, 2009 * @版本 1.0 * */ public class ClassPathApplicationContext { /** * 获取xml文件中的说有bean对应类 */ private List<DefineBean> beanslist = new ArrayList<DefineBean>(); /** * 存储各个实例的键值对 */ private Map<String, Object> sigletons = new HashMap<String, Object>(); /** * 构造函数 * * @param fileName */ public ClassPathApplicationContext(String fileName) { this.readXMLFile(fileName); this.instanceBeans(); } /** * 获取应用实例 * @param beanid * @return */ public Object getBean(String beanid){ return sigletons.get(beanid); } /** * 读取XMl文件 * * @param fileName */ @SuppressWarnings("unchecked") private void readXMLFile(String fileName) { // TODO Auto-generated method stub SAXReader reader = new SAXReader(); Document document = null; try { // 获取XML文件的路径 URL xmlpath = this.getClass().getClassLoader() .getResource(fileName); document = reader.read(xmlpath); Map<String, String> nsMap = new HashMap<String, String>(); nsMap.put("ns", "http://www.springframework.org/schema/beans");// 加入命名空间 XPath xsub = document.createXPath("//ns:beans/ns:bean");// 创建beans/bean查询路径 xsub.setNamespaceURIs(nsMap);// 设置命名空间 List<Element> beans = xsub.selectNodes(document);// 获取文档下所有bean节点 for (Element element : beans) { String id = element.attributeValue("id"); String className = element.attributeValue("class"); DefineBean bean = new DefineBean(id, className); beanslist.add(bean); } } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 实例化所有的bean */ private void instanceBeans() { // TODO Auto-generated method stub for (DefineBean Bean : beanslist) { if (Bean.getClassName() != null && !"".endsWith(Bean.getClassName().trim())) { // 采用java的反射机制进行类的实力化 try { sigletons.put(Bean.getId(), Class.forName( Bean.getClassName()).newInstance()); } 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(); } } } } }
4、PersonServiceImpl及PersonService接口
package com.cvicse.service.impl; import com.cvicse.service.PersonService; /** * * @功能 :测试类的实现 * @创建人 gao_jie * @创建日期 Jun 16, 2009 * @版本 1.0 * */ public class PersonServiceImpl implements PersonService { /* (non-Javadoc) * @see com.cvicse.service.impl.PersonService#save() */ public void save(){ System.out.println("我调用了Save方法!"); } }
package com.cvicse.service; /** * * @功能 :测试类的接口 * @创建人 gao_jie * @创建日期 Jun 16, 2009 * @版本 1.0 * */ public interface PersonService { /** * 保存接口 */ public abstract void save(); }
5.测试类
package com.cvicse.test; import com.cvicse.service.PersonService; import com.cvicse.util.ClassPathApplicationContext; /** * * @功能;测试类 * @创建人 gao_jie * @创建日期 Jun 16, 2009 * @版本 1.0 * */ public class Test { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub ClassPathApplicationContext xp = new ClassPathApplicationContext( "applicationContext.xml"); PersonService personService = (PersonService) xp.getBean("person"); personService.save(); } }
通过简单的测试可以输出:
我调用了Save方法!
呵呵,目的提高自己的编码质量,模拟也是一种进步!