深入理解springioc机制,以下为例子做理解

通过java反射机制来读取applicationContext.xml的内容  该xml文件内容如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    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:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="    
     http://www.springframework.org/schema/beans     
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    
     http://www.springframework.org/schema/tx     
     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd    
     http://www.springframework.org/schema/aop     
     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd    
     http://www.springframework.org/schema/context    
     http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean id="user1" class="com.springioc.entity.User">
        <property name="userId" value="0002"></property>
        <property name="userName" value="张三"></property>
    </bean>
    <bean id="user2" class="com.springioc.entity.User">
        <property name="userId" value="0003"></property>
        <property name="userName" value="李四"></property>
    </bean>


</beans>   

第一步:

1.创建实体类,实体类有userId,userName属性

2.首先创建一个maevn工程  引入依赖

<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>
        <dependency>
            <groupId>org.dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>2.0.0</version>
        </dependency>

第二步:

编写读取类,内容如下

package com.springioc.main;

import java.lang.reflect.Field;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.springioc.entity.User;

public class ClassPathXmlApplicationContext {

    private static String PATH;
    private static String ID;
    private static String CLASS;
    private static String NAME;
    private static String VALUE;

    
    
    public ClassPathXmlApplicationContext(String path){
        init();
        this.PATH = path;
        
    }
    
    public void init(){
        this.ID = "id";
        this.CLASS = "class";
        this.NAME = "name";
        this.VALUE = "value";
    }
    
    
    public Object getBean(String beanId) throws Exception{
        Object objectUser = null;
        boolean flag = false;    //判断在application.xml中能否找到beanId,如果没有找到则返回false
        //1.解析XML
        if (StringUtils.isEmpty(beanId)) {
            return null;
        }
        SAXReader saxReader = new SAXReader();
        //读取apliction.xml的路径,注意是按照相对路径来读取的this.getClass().getClassLoader()是读取到该项目的路径
        Document read = saxReader.read(this.getClass().getClassLoader().getResource(PATH));
        Element rootElement = read.getRootElement();    //读取根标题,即一级标题
        List<Element> elements = rootElement.elements();    //二级标题
        for (Element el2 : elements) {
            String id = el2.attributeValue(this.ID);    //读取到<bean id="user1" class="com.springioc.entity.User">中的id属性
            if (beanId.equals(id)) {
                flag = true;
            }
            
            if (flag) {
                //2.查找对应的Class
                String attrClass = el2.attributeValue(this.CLASS);
                if (attrClass != null) {
                    //3.如果找到对应的Class则用java的反射机制
                    Class<?> forName = Class.forName(attrClass);
                    Object newInstance = forName.newInstance();
                    //4.获取对应的class中里的属性
                    List<Element> el3 = el2.elements();//获取二级标题下的三级标题,然后遍历赋值
                    for (Element element : el3) {
                        String attrName = element.attributeValue(this.NAME);//这个是映射bean的<property name="userId" value="0002"></property>中name属性
                        String attrValue = element.attributeValue(this.VALUE);    //这个是映射bean的<property name="userId" value="0002"></property>中value属性
                        Field declaredField = forName.getDeclaredField(attrName);    //对userId进行修改
                        declaredField.setAccessible(true); //设置私有属性可修改,即private修饰也可以修改
                        declaredField.set(newInstance, attrValue);//将id,name修改即类似set方法
                        objectUser = newInstance;
                    }
                }
                flag = false;    //找到之后对应的bean id之后初始化flag 在进入判断 
            }else {
                new Exception("未找到bean中所对应的id");
            }
        }
        
        return objectUser;
    }
    
    
    
    
    public static void main(String[] args) throws Exception{
        
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User) app.getBean("user1");
        if (user != null) {
            System.out.println(user.toString());
        }else {
            System.out.println("user初始化失败");
        }
    }
    
}
 

猜你喜欢

转载自blog.csdn.net/qq_36973387/article/details/81386306