spring容器简单模拟(一)
简单模拟实现Spring的bean实例化,以及注入bean中的属性.
xml里面东西转换成具体java类
package com.shanzhai;import java.beans.IntrospectionException;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;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;/** * 山寨版spring容器 * * @author Administrator * */public class SZClassPathApplicationContext {private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();private Map<String, Object> sigletons = new HashMap<String, Object>();public SZClassPathApplicationContext(String fileName) {this.readXML(fileName);this.instanceBean();this.injectObject();}/** * xml里面的读取过来,用对象来表示*map来存放实例化bean*取出每个实例化的bean,遍历bean里的每个属性,如果等于pro里面的属性,那么从map里面取出实例化值set到bean里面去. */private void injectObject() {for (BeanDefinition beanDefinition : beanDefines) {Object bean = this.getBean(beanDefinition.getId());if (bean != null) {try {PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();for (Propety p : beanDefinition.getPropeties()) {for (PropertyDescriptor descriptor : ps) {if (descriptor.getName().equals(p.getName())) {Method setter = descriptor.getWriteMethod();if (setter != null) {Object value = sigletons.get(p.getRef());setter.setAccessible(true);setter.invoke(bean, value);}}}}} catch (IntrospectionException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}private void instanceBean() {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();}}}/** * 读取配置文件 * * @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节点for (Element element : beans) {String id = element.attributeValue("id");// 获取id属性值String clazz = element.attributeValue("class"); // 获取class属性值BeanDefinition beanDefine = new BeanDefinition(id, clazz);XPath propertysub = element.createXPath("ns:property");propertysub.setNamespaceURIs(nsMap);// 设置命名空间List<Element> propertys = propertysub.selectNodes(element);for (Element property : propertys) {String propertyName = property.attributeValue("name");String propertyref = property.attributeValue("ref");Propety propertyDefinition = new Propety(propertyName,propertyref);beanDefine.getPropeties().add(propertyDefinition);}beanDefines.add(beanDefine);}} catch (Exception e) {e.printStackTrace();}}/** * 获取bean实例 * * @param beanName * @return */public Object getBean(String beanName) {return this.sigletons.get(beanName);}}