1. 程式人生 > >深入理解springioc機制,以下為例子做理解

深入理解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初始化失敗");
        }
    }
    
}