模拟Spring中的getBean方法

一直知道Spring是运用反射技术的,但具体怎么用呢?今天就模拟下getBean方法。

步骤:

1、用Dom4j解析xml配置文件,取出我们需要的信息

2、遍历Bean节点,根据每个Bean节点的class属性值通过反射生成相应的对象

3、解析Bean节点的子节点,用于给对象的属性赋值(调用set方法)或者其他

4、把每个Bean节点封装好的对象放入Map集合里

具体操作如下:

一、xml配置(自己模拟写的xml)

<?xml version="1.0" encoding="UTF-8"?>
<Beans>
    <Bean Id="user" class="project.test.User">
        <property name="name">Jack</property>
        <property name="pwd">1234</property>
    </Bean>
    <Bean Id="user1" class="project.test.User">
        <property name="name">Jack11</property>
        <property name="pwd">1234111</property>
    </Bean>
</Beans>

二、具体的实现。

User实体类:

package project.test;

public class User {
    private String name;
    private String pwd;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    
}

具体的操作类:

package project.test;

import java.beans.PropertyDescriptor;
import java.io.File;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class BeanFactoryDemo {
    private  Map<String,Object> map = new HashMap<String,Object>();
    public  Map<String,Object> getBeanMap() throws Exception {
         //1、用Dom4j解析xml配置文件,取出我们需要的信息 
        SAXReader reader = new SAXReader();
        //获取一个Document对象
        Document doc =reader.read(new File("resources/demo.xml"));
        //通过XPath获得Beans节点下的所有Bean元素
        List<Element> list = doc.selectNodes("/Beans/Bean");
        //2、遍历Bean节点,根据每个Bean节点的class属性值通过反射生成相应的对象 
//遍历Bean元素,找出我们需要的东西如:Id,class属性值
        for(Element e :list){
            String Id = e.attributeValue("Id");
            String cls = e.attributeValue("class");
            //通过获取到的class属性值获得一个Class对象用于生成相应的对象
            Class clas = Class.forName(cls);
            //通过Class新建一个对象
            Object obj = clas.newInstance();
            //获取Bean的子元素
            Iterator<Element> it = e.elementIterator();
            while(it.hasNext()){
                Element e1 = it.next();
                //获得属性元素的文本内容,便于下面给调用对象的set方法赋值
                String value = e1.getText();
                //获取对应元素的属性列表(如:name)
                List<Attribute> ls = e1.attributes();
                for(Attribute a:ls){
                  //3、解析Bean节点的子节点,用于给对象的属性赋值(调用set方法)或者其他 
//通过PropertyDescriptor获得obj里的方法,第一个参数是属性名,第二个参数是Class对象
                    PropertyDescriptor pd = new PropertyDescriptor(a.getValue(), clas);
                 //获得写方法(set方法)如果要获取get方法即:pd.getReadMethod();
                 Method m = pd.getWriteMethod();
                 //反射调用set方法
                    m.invoke(obj, value);
                }
                
            }
            //4、把每个Bean节点封装好的对象放入Map集合里
            map.put(Id, obj);
        }
        return map;
    }
    public Object getBean(String id) throws Exception{
        return getBeanMap().get(id);
    }
    public static void main(String[] args) throws Exception {
        User u = (User)new BeanFactoryDemo().getBean("user");
        System.out.println(u.getName());
        System.out.println(u.getPwd());
        User u1 = (User)new BeanFactoryDemo().getBean("user1");
        System.out.println(u1.getName());
        System.out.println(u1.getPwd());
    }
}

以上就是我模拟的getBean方法,当然在spring里比这复杂好多,我还在研究。。。。。

只是粗浅的看法,不对的地方请多多指正,毕竟还是个菜鸟

原文地址:https://www.cnblogs.com/liruiloveparents/p/5041088.html