使用dom4j模拟Spring解析

需要解析的xml文件,注意引用ref。


<?xml version="1.0" encoding="UTF-8" ?>
<beans>
<bean id="board1" class="模拟Spring.Board">
<property name="brand" value="华硕"></property>
<property name="price" value="500"></property>
</bean>
<bean id="com1" class="模拟Spring.Computer">
<property name="brand" value="华硕"></property>
<property name="price" value="500"></property>
<property name="board" ref="board1"></property>

</bean>
</beans>

Board类

package 模拟Spring;

/**
* @author duyong_dain@163.com
* @data 2018/10/10 15:36
* @TODO-->
*/
public class Board {
private String brand;
private float price;

public String getBrand() {
return brand;
}

public void setBrand(String brand) {
this.brand = brand;
}

public float getPrice() {
return price;
}

public void setPrice(float price) {
this.price = price;
}

@Override
public String toString() {
return "Board{" +
"brand='" + brand + '\'' +
", price=" + price +
'}';
}
}

Computer类

package 模拟Spring;

/**
* @author duyong_dain@163.com
* @data 2018/10/10 15:36
* @TODO-->
*/
public class Computer {
private String brand;
private float price;
private Board board;

public Board getBoard() {
return board;
}

public void setBoard(Board board) {
this.board = board;
}

public String getBrand() {
return brand;
}

public void setBrand(String brand) {
this.brand = brand;
}

public float getPrice() {
return price;
}

public void setPrice(float price) {
this.price = price;
}

@Override
public String toString() {
return "Computer{" +
"brand='" + brand + '\'' +
", price=" + price +
", board=" + board +
'}';
}
}
package 模拟Spring;


import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @author duyong_dain@163.com
 * @data 2018/10/10 15:36
 * @TODO-->
 */
public class Spring {
    private static Spring instance;
    private Spring(){
        init();
    }
    public static Spring getInstance(){
        if(instance==null)
            instance=new Spring();
        return instance;
    }
//存储bean
    private HashMap<String,Object> beans=new HashMap<>();
    //存储被ref引用的对象的信息

    private List<String[]> refInfos=new ArrayList<>();
    //配置文件路径


    String path= "src/main/java/模拟Spring/beans.xml";

    private void init(){
        /**
        *@TODO:初始化XMl文件,创建对象,填充属性
        *@return: void
        */
        SAXReader reader=new SAXReader();
        try{
            File file=new File(path);
            InputStream in=new FileInputStream(file);
            Document doc=reader.read(in);
            //获取根元素
            Element rootElement=doc.getRootElement();
            //bean迭代器
            Iterator<Element> beanIterator=rootElement.elementIterator();
            while(beanIterator.hasNext()){
                //获取bean
                Element beanElement=beanIterator.next();
                //获取bean的属性对象
                Attribute id=beanElement.attribute("id");
                Attribute classPath=beanElement.attribute("class");
                //创建对象
                Class c=Class.forName(classPath.getValue().trim());
                Object obj=c.newInstance();
                //属性的填充
                Iterator<Element> propertyIterator=beanElement.elementIterator();
                while(propertyIterator.hasNext()){
                    //property对象
                    Element propertyElement=propertyIterator.next();
                    Attribute propertyname=propertyElement.attribute("name");

                    //获取name属性的值
                    String name=propertyname.getValue();

                    Attribute propertyvalue=propertyElement.attribute("value");
                    if(propertyvalue==null){
                        //ref
                        Attribute propertyRef=propertyElement.attribute("ref");
                        //ref引用的是容器中的其他对象,暂时记录信息
                        //记录对象的ID,属性的名称,ref的值
                        String[] refInfo={id.getValue(),name,propertyRef.getValue()};
                        refInfos.add(refInfo);
                    }
                    else{
                           //普通属性
                        String value=propertyvalue.getValue();
                        setAttr(obj,name,value);
                    }

                }

beans.put(id.getValue(),obj);
            }
            //有ref的对象没有装配,在这里等所有的对象都创建后开始装配
            for(String[] infos:refInfos){
                Object obj=beans.get(infos[0]);//获取map中key(id)对应的对象
                String attrName=infos[1];//拿到需要装配的name信息
                Object targetObj=beans.get(infos[2]);//拿到ref所指向的对象
                String methodName="set"+attrName.substring(0,1).toUpperCase()+attrName.substring(1);
                Method setMethod=null;
                Class c=obj.getClass();
                Method[] methods=c.getMethods();
                for(Method method:methods){
                    if(method.getName().equals(methodName)){
                        setMethod=method;
                        break;
                    }
                }
                if(setMethod==null){
                    throw  new RuntimeException("方法"+methodName+"没有找到");
                }
                setMethod.invoke(obj,targetObj);

            }
        }
         catch (Exception e){
            throw new RuntimeException(e);
         }

    }
    private void setAttr(Object obj,String attrName,String attrValue) throws Exception {
               String methodName="set"+attrName.substring(0,1).toUpperCase()+attrName.substring(1);
        Method setMethod=null;
        Class c=obj.getClass();
        Method[] methods=c.getMethods();
        for(Method method:methods){
            if(method.getName().equals(methodName)){
                setMethod=method;
                break;
            }
        }
        if(setMethod==null){
            throw  new RuntimeException("方法"+methodName+"没有找到");
        }
        Class[] parameterTypes=setMethod.getParameterTypes();
        Class parameterType=parameterTypes[0];
        if(parameterType==int.class){
            setMethod.invoke(obj,Integer.parseInt(attrValue));
        }
        if(parameterType==byte.class){
            setMethod.invoke(obj,Byte.parseByte(attrValue));
        }
        if(parameterType==short.class){
            setMethod.invoke(obj,Short.parseShort(attrValue));
        }
        if(parameterType== long.class){
            setMethod.invoke(obj,Long.parseLong(attrValue));
        }
        if(parameterType==float.class){
            setMethod.invoke(obj,Float.parseFloat(attrValue));
        }
        if(parameterType==double.class){
            setMethod.invoke(obj,Double.parseDouble(attrValue));
        }
        if(parameterType==boolean.class){
            setMethod.invoke(obj,Boolean.parseBoolean(attrValue));
        }
        if(parameterType==String.class){
            setMethod.invoke(obj,attrValue);
        }


    }
    public Object getBean(String id){
        return beans.get(id);
    }
    public <T> T getBean(Class c){
        //遍历map
        Set<String> keys=beans.keySet();
        int count=0;
        T t=null;
        for(String key:keys){
            Object obj=beans.get(key);
            if(c==obj.getClass()){
                 t= (T) c.cast(obj);
                 count++;
                 if(count>1){
                     throw  new RuntimeException(c+"出现了俩儿");
                 }
            }
        }
        return null;
    }

    public static void main(String[] args) {
         Spring s=new Spring();
         System.out.println(s.getBean("com1"));
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值