Spring简单模拟Spring容器
续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!
工程目录结构图