续Spring之HelloWorld:http://huangminwen.iteye.com/admin/blogs/1040405
Spring容器启动后,首先读取spring.xml配置文件中的bean信息,然后再实例化该bean,所以我们就可以直接获取bean来使用了,而无需实例化,下面我们模拟一下Spring容器的工作原理,首先我们需要先读取spring.xml配置文件,然后再初始化bean标签页中的类,SimulateClassPathXMLApplicationContext说明了该过程:
package org.spring.junit; 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.Element; import org.dom4j.XPath; import org.dom4j.io.SAXReader; public class SimulateClassPathXMLApplicationContext { private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>(); private Map<String, Object> sigletons = new HashMap<String, Object>(); public SimulateClassPathXMLApplicationContext(String filename) { this.readXML(filename); this.instanceBeans(); } /** * 读取xml配置文件 * * @param filename */ private void readXML(String filename) { SAXReader saxReader = new SAXReader(); Document document = null; try { URL xmlpath = this.getClass().getClassLoader() .getResource(filename); document = saxReader.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节点 // 将读取到的bean信息存入beanDefines中 for (Element element : beans) { String id = element.attributeValue("id");// 获取id属性值 String clazz = element.attributeValue("class"); // 获取class属性值 BeanDefinition beanDefine = new BeanDefinition(id, clazz); beanDefines.add(beanDefine); } } catch (Exception e) { e.printStackTrace(); } } /** * 完成bean的实例化 */ private void instanceBeans() { for (BeanDefinition beanDefinition : beanDefines) { try { if (beanDefinition.getClassName() != null && !"".equals(beanDefinition.getClassName().trim())) sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()) .newInstance()); } catch (Exception e) { e.printStackTrace(); } } } /** * 获取bean实例 * * @param beanName * @return */ public Object getBean(String beanName) { return this.sigletons.get(beanName); } }
其中BeanDefinition类如下:
package org.spring.junit; /** * 用于存放spring.xml中bean标签的信息 */ public class BeanDefinition { private String id; // spring.xml配置文件中bean节点的id属性 private String className; // spring.xml配置文件中的bean节点的name属性 public BeanDefinition(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; } }
控制台打印结果:Hello Spring World!
工程目录结构图