模拟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.输出结果如图所示