使用java反射机制和dom4j写一个简版spring-ioc

1.新建一个springboot项目

	com.springioc
    spring-ioc
    1.0-SNAPSHOT

2.在pom文件中引入

		
            org.apache.commons
            commons-lang3
            3.10
        

        
            dom4j
            dom4j
            1.6.1
        

3.创建一个User对象

package com.entity;

public class User {

    private String id;

    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

4.在resource文件中创建一个application.xml文件




	
		
		
	

	
		
		
	


5.创建一个ClassPathXmlApplicationContext类实现装在bean并赋值返回一个bean实例

package com;

import com.entity.User;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.List;

/**
 * Created by vn0790t on 2020/5/15.
 */
public class ClassPathXmlApplicationContext {

    private String ID; ;
    private String CLASSA;
    private String NAME;
    private String VALUE;

    public ClassPathXmlApplicationContext(){
        init();
    }

    public void init(){
        ID = "id";
        CLASSA = "class";
        NAME = "name";
        VALUE = "value";
    }

    public Object getBean(String beanName) throws Exception {
        SAXReader reader = new SAXReader();
        //定位到resources目录
        URL resource = this.getClass().getClassLoader().getResource("application.xml");
        File file = new File(resource.getFile());
        //读取application.xml配置文件
        Document document = reader.read(file);

        //获取标签beans(一级标签)
        Element rootElement = document.getRootElement();
        //获取beans下的子标签bean(二级标签)
        List elements = rootElement.elements();
        for (Element element : elements){
            //获取bean标签中id属性的值
            String id = element.attributeValue(ID);
            //如果不是要找的beanName就结束本次循环,开始下次循环
            if(!id.equals(beanName)){
                continue;
            }

            //获取bean标签中的class属性的值
            String claessPath = element.attributeValue(CLASSA);
            Class forName = Class.forName(claessPath);
            //使用无参构造函数创建bean对象
            Object newInstance = forName.newInstance();

            //获取bean下的子集标签property(三级标签)
             List eson = element.elements();
            for (Element e : eson){
                //获取属性名name的值
                String name = e.attributeValue(NAME);
                //获取属性名value的值
                String value = e.attributeValue(VALUE);
                //获取bean对象的属性
                Field field = forName.getDeclaredField(name);
                //设置权限(因为属性是私有化的,所以需要设置权限)
                field.setAccessible(true);
                //将bean对象的属性赋值
                field.set(newInstance,value);
            }

            return newInstance;
        }

        return null;
    }

    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext();
        try {
            User user= (User)classPathXmlApplicationContext.getBean("user1");
            System.out.println(user);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

6.SpringIOC底层原理

1.读取bean的XML配置文件
2.使用beanId查找bean配置,并获取配置文件中class地址。
3.使用Java反射技术实例化对象
4.获取属性配置,使用反射技术进行赋值。

详细步骤如下:

1.利用传入的参数获取xml文件的流,并且利用dom4j解析成Document对象
2.对于Document对象获取根元素对象后对下面的标签进行遍历,判断是否有符合的id.
3.如果找到对应的id,相当于找到了一个Element元素,开始创建对象,先获取class属性,根据属性值利用反射建立对象.
4.遍历标签下的property标签,并对属性赋值.注意,需要单独处理int,float类型的属性.因为在xml配置中这些属性都是以字符串的形式来配置的,因此需要额外处理.
5.如果属性property标签有ref属性,说明某个属性的值是一个对象,那么根据id(ref属性的值)去获取ref对应的对象,再给属性赋值.
6.返回建立的对象,如果没有对应的id,或者下没有子标签都会返回null

你可能感兴趣的:(java技术点总结)