模拟spring中的ClassPathXmlApplicationContext的实现

最近,看spring,觉得spring的一些源码,很牛就来模仿下,模仿的目的不是为了炫耀啥,只是提高自己的编码质量。

要模仿ClassPathXmlApplicationContext类的实现,首先要读取spring中applicationContext.xml的内容,同时还要生成类的实例,自然用到的技术就有 dom4j的操作、再就是java 的反射机制、路径操作。

为了测试我在applicationContext.xml中添加了一个bean。

1、applicationContext.xml文件的内容如下:

Xml代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">  
  5.  <bean id="person" class="com.cvicse.service.impl.PersonServiceImpl" />  
  6. </beans>  

 2、为了存取bean的信息,我们定义一个definebean的pojo类

Java代码
  1. package com.cvicse.bean;   
  2.   
  3. /**  
  4.  *   
  5.  * @功能:存储bean的pojo类  
  6.  * @创建人 gao_jie  
  7.  * @创建日期 Jun 16, 2009  
  8.  * @版本 1.0  
  9.  *   
  10.  */  
  11. public class DefineBean {   
  12.   
  13.     private String id;   
  14.     private String className;   
  15.   
  16.     public DefineBean(String id, String className) {   
  17.         this.id = id;   
  18.         this.className = className;   
  19.     }   
  20.   
  21.     public String getId() {   
  22.         return id;   
  23.     }   
  24.   
  25.     public void setId(String id) {   
  26.         this.id = id;   
  27.     }   
  28.   
  29.     public String getClassName() {   
  30.         return className;   
  31.     }   
  32.   
  33.     public void setClassName(String className) {   
  34.         this.className = className;   
  35.     }   
  36. }  

 

3、实现ClassPathXmlApplicationContext类

Java代码
  1. package com.cvicse.util;   
  2.   
  3. import java.net.URL;   
  4. import java.util.ArrayList;   
  5. import java.util.HashMap;   
  6. import java.util.List;   
  7. import java.util.Map;   
  8.   
  9. import org.dom4j.Document;   
  10. import org.dom4j.DocumentException;   
  11. import org.dom4j.Element;   
  12. import org.dom4j.XPath;   
  13. import org.dom4j.io.SAXReader;   
  14.   
  15. import com.cvicse.bean.DefineBean;   
  16.   
  17. /**  
  18.  *   
  19.  * @功能 ClassPathApplicationContext类  
  20.  * @创建人 gao_jie  
  21.  * @创建日期 Jun 16, 2009  
  22.  * @版本 1.0  
  23.  *   
  24.  */  
  25. public class ClassPathApplicationContext {   
  26.   
  27.     /**  
  28.      * 获取xml文件中的说有bean对应类  
  29.      */  
  30.     private List<DefineBean> beanslist = new ArrayList<DefineBean>();   
  31.   
  32.     /**  
  33.      * 存储各个实例的键值对  
  34.      */  
  35.     private Map<String, Object> sigletons = new HashMap<String, Object>();   
  36.   
  37.     /**  
  38.      * 构造函数  
  39.      *   
  40.      * @param fileName  
  41.      */  
  42.     public ClassPathApplicationContext(String fileName) {   
  43.         this.readXMLFile(fileName);   
  44.         this.instanceBeans();   
  45.     }   
  46.        
  47.     /**  
  48.      * 获取应用实例  
  49.      * @param beanid  
  50.      * @return  
  51.      */  
  52.     public Object getBean(String beanid){   
  53.         return sigletons.get(beanid);   
  54.     }   
  55.   
  56.     /**  
  57.      * 读取XMl文件  
  58.      *   
  59.      * @param fileName  
  60.      */  
  61.     @SuppressWarnings("unchecked")   
  62.     private void readXMLFile(String fileName) {   
  63.         // TODO Auto-generated method stub   
  64.         SAXReader reader = new SAXReader();   
  65.         Document document = null;   
  66.         try {   
  67.             <STRONG><SPAN style="COLOR: #ff0000">// 获取XML文件的路径   
  68.             URL xmlpath = this.getClass().getClassLoader()   
  69.                     .getResource(fileName);</SPAN></STRONG>   
  70.         <SPAN style="COLOR: #000080"><STRONG>   document = reader.read(xmlpath);   
  71.             Map<String, String> nsMap = new HashMap<String, String>();   
  72.             nsMap.put("ns""http://www.springframework.org/schema/beans");// 加入命名空间   
  73.             XPath xsub = document.createXPath("//ns:beans/ns:bean");// 创建beans/bean查询路径   
  74.             xsub.setNamespaceURIs(nsMap);// 设置命名空间   
  75.             List<Element> beans = xsub.selectNodes(document);// 获取文档下所有bean节点   
  76.             for (Element element : beans) {   
  77.                 String id = element.attributeValue("id");   
  78.                 String className = element.attributeValue("class");   
  79.                 DefineBean bean = new DefineBean(id, className);   
  80.                 beanslist.add(bean);   
  81.             }</STRONG></SPAN>   
  82.         } catch (DocumentException e) {   
  83.             // TODO Auto-generated catch block   
  84.             e.printStackTrace();   
  85.         }   
  86.     }   
  87.   
  88.     /**  
  89.      * 实例化所有的bean  
  90.      */  
  91.     private void instanceBeans() {   
  92.         // TODO Auto-generated method stub   
  93.         for (DefineBean Bean : beanslist) {   
  94.   
  95.             if (Bean.getClassName() != null  
  96.                     && !"".endsWith(Bean.getClassName().trim())) {   
  97.                 // 采用java的反射机制进行类的实力化   
  98.                 try {   
  99.                     <SPAN style="COLOR: #ff0000"><STRONG>sigletons.put(Bean.getId(), Class.forName(   
  100.                             Bean.getClassName()).newInstance());</STRONG></SPAN>   
  101.                 } catch (InstantiationException e) {   
  102.                     // TODO Auto-generated catch block   
  103.                     e.printStackTrace();   
  104.                 } catch (IllegalAccessException e) {   
  105.                     // TODO Auto-generated catch block   
  106.                     e.printStackTrace();   
  107.                 } catch (ClassNotFoundException e) {   
  108.                     // TODO Auto-generated catch block   
  109.                     e.printStackTrace();   
  110.                 }   
  111.             }   
  112.         }   
  113.     }   
  114. }  

 

4、PersonServiceImpl及PersonService接口

Java代码
  1. package com.cvicse.service.impl;   
  2.   
  3. import com.cvicse.service.PersonService;   
  4.   
  5. /**  
  6.  *   
  7.  * @功能 :测试类的实现    
  8.  * @创建人   gao_jie  
  9.  * @创建日期 Jun 16, 2009  
  10.  * @版本     1.0  
  11.  *   
  12.  */  
  13. public class PersonServiceImpl implements PersonService {   
  14.        
  15.     /* (non-Javadoc)  
  16.      * @see com.cvicse.service.impl.PersonService#save()  
  17.      */  
  18.     public void save(){   
  19.         System.out.println("我调用了Save方法!");   
  20.     }   
  21. }  

 

Java代码
  1. package com.cvicse.service;   
  2.   
  3. /**  
  4.  *   
  5.  * @功能 :测试类的接口      
  6.  * @创建人   gao_jie  
  7.  * @创建日期 Jun 16, 2009  
  8.  * @版本     1.0  
  9.  *   
  10.  */  
  11. public interface PersonService {   
  12.   
  13.     /**  
  14.      * 保存接口  
  15.      */  
  16.     public abstract void save();   
  17. }  

 5.测试类

Java代码
  1. package com.cvicse.test;   
  2.   
  3. import com.cvicse.service.PersonService;   
  4. import com.cvicse.util.ClassPathApplicationContext;   
  5.   
  6. /**  
  7.  *   
  8.  * @功能;测试类  
  9.  * @创建人 gao_jie  
  10.  * @创建日期 Jun 16, 2009  
  11.  * @版本 1.0  
  12.  *   
  13.  */  
  14. public class Test {   
  15.   
  16.     /**  
  17.      * @param args  
  18.      */  
  19.     public static void main(String[] args) {   
  20.         // TODO Auto-generated method stub   
  21.         ClassPathApplicationContext xp = new ClassPathApplicationContext(   
  22.                 "applicationContext.xml");   
  23.         PersonService personService = (PersonService) xp.getBean("person");   
  24.         personService.save();   
  25.     }   
  26. }  

 通过简单的测试可以输出: 

 我调用了Save方法!

呵呵,目的提高自己的编码质量,模拟也是一种进步!

你可能感兴趣的:(java,spring,bean,String,测试,Class)