springIOC实现原理模拟(springIOC底层使用xml解析+反射实现)
springIOC底层使用xml解析+反射实现。
模拟ClassPathXmlApplicationContext:
import java.io.File; import java.lang.reflect.Field; import java.util.Iterator; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class ClassPathXmlApplicationContextCopy { private Document document; public ClassPathXmlApplicationContextCopy(String location){ // 解析xml parseXML(location); } private void parseXML(String location) { try { SAXReader saxReader = new SAXReader(); Document document = saxReader.read(new File(location)); this.document = document; } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public Object getBean(String name){ // 1.根据name匹配到bean。2.根据节点中class的值反射实例化。3.遍历子节点set值。 // 匹配对应bean Element root = document.getRootElement(); Iterator beans = root.elementIterator(); Object instance = null; while(beans.hasNext()){ Element ele = (Element) beans.next(); if(name.equals(ele.attributeValue("id"))){ String classPath = ele.attributeValue("class"); try { Class<?> clazz = Class.forName(classPath); // 反射实例化 instance = clazz.newInstance(); // set值 Iterator nodes = ele.elementIterator(); while(nodes.hasNext()){ Element node = (Element) nodes.next(); String fieldName = node.attributeValue("name"); String fieldValue = node.attributeValue("value"); try { Field f = clazz.getDeclaredField(fieldName); f.setAccessible(true); f.set(instance, fieldValue); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } // 有get*(String *)方法 /*for(Field f : clazz.getDeclaredFields()){ if(f.getName().equals(fieldName)){ f.setAccessible(true); f.set(instance, fieldValue); } }*/ } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } } } return instance; } }
测试:
public class Test { /** * @param args */ public static void main(String[] args) { ClassPathXmlApplicationContextCopy ctx = new ClassPathXmlApplicationContextCopy("D:/eclipse-jee-juno-win32/eclipse/workspace/SpringTest/resources/applicationContext.xml"); UserEntity userEntity = (UserEntity) ctx.getBean("user2"); System.out.println(userEntity.getUserId() + ":" + userEntity.getUserName()); /*SpringHelper springHelper = (SpringHelper) ctx.getBean("springHelper"); ProcessEngine processEngine = springHelper.createProcessEngine(); List<HistoryTask> hisTaskList = processEngine.getHistoryService().createHistoryTaskQuery().list(); for(HistoryTask hisTask : hisTaskList){ System.out.println(hisTask.getId() + ":" + hisTask.getAssignee()); }*/ } }
结果:
无参构造函数执行...
0002:张三
spring的applicationContext.xml配置:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <bean id="user1" class="com.test.UserEntity"> <property name="userId" value="0001"></property> <property name="userName" value="李四"></property> </bean> <bean id="user2" class="com.test.UserEntity"> <property name="userId" value="0002"></property> <property name="userName" value="张三"></property> </bean> </beans>