模拟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.输出结果如图所示
模拟stringBeanFactory解析xml的更多相关文章
- 使用JDom解析XML文档模拟Spring的配置文件解析
在J2EE项目中可能会涉及到一些框架的使用,最近接触到了SSH,拿Spring来说配置文件的使用是相当重要的,Spring的配置文件是一个xml文件,Spring是如何读取到配置文件并进行依赖注入的呢 ...
- Java从零开始学四十二(DOM解析XML)
一.DOM解析XML xml文件 favorite.xml <?xml version="1.0" encoding="UTF-8" standalone ...
- Android网络之数据解析----SAX方式解析XML数据
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...
- (四)SAX方式解析XML数据
SAX方式解析XML数据 文章来源:http://www.cnblogs.com/smyhvae/p/4044170.html 一.XML和Json数据的引入: 通常情况下,每个需要访问网络的应用程 ...
- Android -- 创建XML文件对象及其序列化, pull解析XML文件
1. 创建XML文件对象及其序列化 示例代码:(模拟以xml格式备份短信到SD卡) SmsInfo.java, bean对象 /** * 短信的业务bean * @author Administrat ...
- JQuery -- Jquery 中的Ajax, Jquery解析xml文件
1. JQuery 对 Ajax 操作进行了封装,在 jQuery 中最底层的方法时 $.ajax(), 第二层是 load(), $.get() 和 $.post(),第三层是$.getScript ...
- 扒一扒spring,dom4j实现模拟实现读取xml
今天leadr提出需求,原来公司项目中读取解析xml文件的代码效率太低,考虑切换一种xml为数据封装格式与读取方式以提高效率.我这灵机一动spring对bean的依赖注入就是读取xml文件,可以尝试扒 ...
- 网络相关系列之四:数据解析之SAX方式解析XML数据
一.XML和Json数据的引入: 通常情况下.每一个须要訪问网络的应用程序都会有一个自己的server.我们能够向server提交数据,也能够从server获取数据.只是这个时候就有一个问题,这些数据 ...
- Android 解析XML文件和生成XML文件
解析XML文件 public static void initXML(Context context) { //can't create in /data/media/0 because permis ...
随机推荐
- LeetCode算法题-Find Smallest Letter Greater Than Target(Java实现)
这是悦乐书的第306次更新,第326篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第175题(顺位题号是744).给定一个仅包含小写字母的有序字符数组,并给定目标字母目标 ...
- Clion快捷键
快捷键配置 File->Setting->Keymap->Keymaps 选择Visual Studio风格 代码提示的匹配模式 File->Setting->Edito ...
- C# 中利用 CRC32 值判断文件是否重复
需要在 NuGet 中引用 Crc32.NET 包 直接贴代码了: using Force.Crc32; using System; using System.Collections.Generic; ...
- Thymeleaf入门(一)——入门与基本概述
一.概述 1.是什么 简单说, Thymeleaf 是一个跟 Velocity.FreeMarker 类似的模板引擎,它可以完全替代 JSP . 2.feature 1.Thymeleaf 在有网络和 ...
- Effective C++ 第0章 copy constructor和copy assignment operator
拷贝构造函数(copy constructor)被用来以一个对象来初始化同类型的另一个对象,拷贝赋值运算符(copy assignment operator)被用来将一个对象中的值拷贝到同类型的另一个 ...
- 系统运行缓慢,CPU 100%,以及Full GC次数过多问题的排查思路
前言 处理过线上问题的同学基本上都会遇到系统突然运行缓慢,CPU 100%,以及Full GC次数过多的问题.当然,这些问题的最终导致的直观现象就是系统运行缓慢,并且有大量的报警. 本文主要针对系统运 ...
- uniApp——v-for 动态class、动态style
:class="i.themColor" <view v-for="i in htmlJSON" class="column" :c ...
- Tree 和ls 的使用
再次声明:linux下的文件系统采用树的结构实现的 我们 可以安装 Tree 软件 在当前目录下(随便一个当前目录下)输入 tree 命令,我们可以看到整个当前文件目录下的目录以及文件的树状结构,这也 ...
- C++购书系统
C++购书系统——来自班里某位同学的小学期作业 这是一个购书系统,模拟网上购书的流程.用户可以在这个小程序里输入对应的数字进行浏览书籍信息,查看用户信息,查找书籍,购买书籍以及查询个人订单的操作. 以 ...
- jdbc连接字符串
MySQL:String Driver="com.mysql.jdbc.Driver"; //驱动程序String URL="jdbc:mysql://localhost ...