Fork me on GitHub

模拟stringBeanFactory解析xml

思路:根据源码分析,将配置Bean类信息存放到xml文件中,通过解析xml,

然后反射拿到对象 存放到集合中 这里选择hashmap(键放置类名,值放置对象)存放,使用时使用get方法通过键(类名)拿到值(对象)。

后续需要优化的:自动清理缓存垃圾,因为初始化加载把所有的对象都存放进去,造成太多不必要的垃圾对象,导致占用内存,效率低。

1.导入主要工具包 dom4j.jar

2.创建一个javaBean类(注意要添加构造器,因为使用反射)

package com.ms.bean;

/*
 * 
 * Person bean
 * **/

public class Person {
    
    private String name;
    private int age;
    
    
    public Person() {
		super();
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public void info(){
        System.out.println("this is a people");
        System.out.println("name:  "+getName()+" age:  "+getAge());
    }
}

 3.创建一个SpringBeanFactory工厂类

package com.ms.utils;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 
 * 模拟spring 加载xml配置文件(dom4j)
 *
 */
public class SpringBeanFactory {
    //初始化的bean全用map集合保存
    public static Map<String,Object> beanMap = new HashMap<String, Object>();

   
    /**
     * 解析xml 并且保存到beanmap中
     * 
     */
    public static void parse(String xml){
        SAXReader reader = new SAXReader();
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        //从class目录下获取指定的xml
        InputStream is = classLoader.getResourceAsStream(xml);
         //根节点
         Document doc=null;
			try {
				doc = reader.read(is);
				 Element rootElement = doc.getRootElement();
		            
		         Element foo;
		            //用迭代器遍历bean
		            for (Iterator i =rootElement.elementIterator("bean");i.hasNext();){
		                foo = (Element) i.next();
		                //获取id和class
		                Attribute id = foo.attribute("id");
		                Attribute aClass = foo.attribute("class");
		                //利用反射机制获取Class对象
		                Class bean = Class.forName(aClass.getText());
		                //获取class信息
		                BeanInfo info = Introspector.getBeanInfo(bean);
		                //获取其属性描述
		                PropertyDescriptor pd[] = info.getPropertyDescriptors();
		                //设置方法
		                Method mSet = null;
		                //创建一个对象
		                Object obj = bean.newInstance();
		                //遍历该bean的property属性
		                for (Iterator ite = foo.elementIterator("property");ite.hasNext();){
		                    Element foo2 = (Element) ite.next();
		                    //获取name的属性
		                    Attribute name = foo2.attribute("name");
		                    //获取value值
		                    Attribute value = foo2.attribute("value");
		                    for (PropertyDescriptor pp : pd) {
		                        if (pp.getName().equalsIgnoreCase(name.getText())){
		                            mSet = pp.getWriteMethod();
		                            Class<?>[] types = mSet.getParameterTypes();
		                            for (Class<?> type : types) {
		                                if (type.getName().equals("int")){
		                                    //转换为整型
		                                    mSet.invoke(obj,Integer.parseInt(value.getText()));
		                                }else {
		                                    //利用java反射调用set方法
		                                    mSet.invoke(obj,value.getText());
		                                }
		                            }

		                        }
		                    }
		                }
		                beanMap.put(id.getText(),obj);
		            }
			} catch (DocumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (NumberFormatException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IntrospectionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
           

        
    }
}

 4.创建一个mySpringBean.xml 放置在src目录下面

<?xml version="1.0" encoding="UTF-8"?>
<beans>
   <bean id="person" class="com.ms.bean.Person">
        <property name="name" value="jack"/>
        <property name="age" value="20"/>
    </bean>
  
</beans>

 5.创建测试类

package test;

import org.junit.Test;

import com.ms.bean.Person;
import com.ms.dao.IString;
import com.ms.dao.myString;
import com.ms.utils.SpringBeanFactory;

/**
 * this is a test
 * 
 * */

public class test {

	public test() {
		 SpringBeanFactory.parse("myStringBean.xml");
	}
	
	@Test
	public void testPerson(){
	
	     Person person = (Person)SpringBeanFactory.beanMap.get("person");
	     person.info();
    }
	
}

  6.输出结果如图所示

 

posted @ 2019-02-24 17:03  雪人奥特曼  阅读(217)  评论(0编辑  收藏  举报