思路:根据源码分析,将配置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.输出结果如图所示

模拟stringBeanFactory解析xml的更多相关文章

  1. 使用JDom解析XML文档模拟Spring的配置文件解析

    在J2EE项目中可能会涉及到一些框架的使用,最近接触到了SSH,拿Spring来说配置文件的使用是相当重要的,Spring的配置文件是一个xml文件,Spring是如何读取到配置文件并进行依赖注入的呢 ...

  2. Java从零开始学四十二(DOM解析XML)

    一.DOM解析XML xml文件 favorite.xml <?xml version="1.0" encoding="UTF-8" standalone ...

  3. Android网络之数据解析----SAX方式解析XML数据

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...

  4. (四)SAX方式解析XML数据

    SAX方式解析XML数据 ​文章来源:http://www.cnblogs.com/smyhvae/p/4044170.html 一.XML和Json数据的引入: 通常情况下,每个需要访问网络的应用程 ...

  5. Android -- 创建XML文件对象及其序列化, pull解析XML文件

    1. 创建XML文件对象及其序列化 示例代码:(模拟以xml格式备份短信到SD卡) SmsInfo.java, bean对象 /** * 短信的业务bean * @author Administrat ...

  6. JQuery -- Jquery 中的Ajax, Jquery解析xml文件

    1. JQuery 对 Ajax 操作进行了封装,在 jQuery 中最底层的方法时 $.ajax(), 第二层是 load(), $.get() 和 $.post(),第三层是$.getScript ...

  7. 扒一扒spring,dom4j实现模拟实现读取xml

    今天leadr提出需求,原来公司项目中读取解析xml文件的代码效率太低,考虑切换一种xml为数据封装格式与读取方式以提高效率.我这灵机一动spring对bean的依赖注入就是读取xml文件,可以尝试扒 ...

  8. 网络相关系列之四:数据解析之SAX方式解析XML数据

    一.XML和Json数据的引入: 通常情况下.每一个须要訪问网络的应用程序都会有一个自己的server.我们能够向server提交数据,也能够从server获取数据.只是这个时候就有一个问题,这些数据 ...

  9. Android 解析XML文件和生成XML文件

    解析XML文件 public static void initXML(Context context) { //can't create in /data/media/0 because permis ...

随机推荐

  1. json和java对象相互转换

    json和java对象相互转换 springboot中json转换默认使用的是jackson包,通过spring-boot-starter-web依赖的 1 在属性上添加注解@JsonFormat(p ...

  2. 小功能 HTML标签状态改变

    在编写程序得时候根据不同的业务需求会改变相应的标签的状态 今天介绍一下<a>标签状态的改变 当前业务场景为需要A标签的样式 即保留A标签的原有样式 在鼠标悬停得时候鼠标状态呈销售状 都知道 ...

  3. 算法01 C语言设计

    8.21 #include <stdio.h> void bubbleSort(int **p, int n); int main(void){ int a[100]; int *b[10 ...

  4. js循环获取table中的值

    <script type="text/javascript"> function getTdValue() { var tableId = document.getEl ...

  5. 牛客网:将两个单调递增的链表合并为一个单调递增的链表-Python实现-两种方法讲解

    方法一和方法二的执行效率,可以大致的计算时间复杂度加以对比,方法一优于方法二   1. 方法一: 思路: 1. 新创建一个链表节点头,假设这里就叫 head3: 2. 因为另外两个链表都为单调递增,所 ...

  6. flutter 自定义主题切换

    1. 定义local_srorage.dart文件 使用Flutter第三方插件shared_preferences实现存储键值对信息 相关shared_preferences插件可参考: flutt ...

  7. sql 语句中as的用法和作用

    我们的Sql语句在很多数据库中都是通用的,比如像Mysql数据库 Access数据库. Oracle数据库.  Sqlite数据库 .甚至在我们的Excel中也可以使用Sql语句. 在我的数据库中有u ...

  8. pypinyin, jieba分词与Gensim

    一 . pypinyin from pypinyin import lazy_pinyin, TONE, TONE2, TONE3 word = '孙悟空' print(lazy_pinyin(wor ...

  9. CS程序自动更新实现原理及代码(支持多版本多文件更新)

    公司主要项目为CS端,经常遇到客户需求变更及bug处理,在没有引用自动更新之前每次更新程序,必须手动对每个客户端进行更新,这样导致技术支持工作量特别大,也给客户不好的印象,因此我需要一个自动更新程序! ...

  10. CountDownLatch类实现同步

    首先我们看一个普通的多线程代码 class MyThread implements Runnable { @Override public void run() { System.out.printl ...