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>

 

posted @ 2021-06-24 13:27  super超人  阅读(130)  评论(0编辑  收藏  举报