主要涉及知识点:xml解析,反射
xml解析(4中解析方式)
DOM解析:对于特别大的文档,解析和加载整个文档可能很慢且很耗资源,因此使用其他手段来处理这样的数据会更好,对性能和内存的要求比较高,尤其是遇到很大的 XML 文件的时候。由于它的遍历能力,DOM 解析器常用于 XML 文档需要频繁的改变的服务中。
SAX 解析: 采用了基于事件的模型,它在解析 XML 文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX 对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag。特别是当开发人员只需要处理文档中所包含的部分数据时,SAX 这种扩展能力得到了更好的体现。但用 SAX 解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。
DOM4J解析:是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J。(用的比较多,下面的内容也是这种解析方式)
javaBean创建如下:
package wxtest.tezxt;
public class User {
private int id;
private String name;
private String address;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
xml配置如下:(当前的xml一定是在根目录下面 也就是在resources下 否则找不到对应的路径)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--spring注入方式1-set注入-->
<!-- <bean id="person" class="wxtest.tezxt.User">
<property name="id" value="1111"/>
<property name="address" value="北京"/>
<property name="name" value="xiaoxiao"/>
</bean>-->
<!--spring注入方式2-构造器注入-->
<bean id="person" class="wxtest.tezxt.User">
<!-- <constructor-arg index="0" value="2222"/>
<constructor-arg index="1" value="344"/>
<constructor-arg index="2" value="5667675"/>-->
</bean>
</beans>
有了javaBean和对应的xml 我们如何让两者建立联系 从而使xml的配置去帮我们创建对象呢?首先我们想到我们正常的得到java对象的代码如下:
那么我们首先创建一个类似ClassPathXmlApplicationContext的类,然后去解析spring.xml文件 去遍历去xml文件所有的bean对应的id 和class 这样我们就可以找到我们要得到的getBean("beanId")是否存在不:
package wxtest.HandwriteSpring;
import org.apache.poi.ss.formula.functions.T;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import wxtest.tezxt.User;
import java.io.InputStream;
import java.util.List;
// 思路 通过使用spring的配置获取对象的方式顺推
// 1.读取xml 获取所有的元素
// 2.将所传的id与解析的元素作比较
// 3.利用反射找出对应的类
public class HandwriteClassPathXmlApplicationContext {
private String xmlPath;
public HandwriteClassPathXmlApplicationContext(String xmlPath) {
this.xmlPath = xmlPath;
}
public Object getBean(String beanId) throws Exception {
Class <T> tClass = (Class <T>) Class.forName(getBeanClass(beanId));
return tClass.newInstance();
}
private String getBeanClass(String beanId) throws Exception {
SAXReader saxReader = new SAXReader();
String className = null;
Document document = saxReader.read(getXMLPath(xmlPath));
Element element = document.getRootElement();
List <Element> elements = element.elements();
if (elements == null && elements.isEmpty()) {
System.out.println("bean是空的");
}
for (Element ele : elements) {
String str = ele.attributeValue("id");
if (str == null) {
System.out.println("没有对应的beanId");
throw new Exception("没有对应的beanId");
}
if (!str.equals(beanId)) {
continue;
}
if (str.equals(beanId)) {
className = ele.attributeValue("class");
}
}
return className;
}
private InputStream getXMLPath(String xmlPath) {
InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream(xmlPath);
return resourceAsStream;
}
public static void main(String[] args) throws Exception {
HandwriteClassPathXmlApplicationContext handwriteClassPathXmlApplicationContext = new HandwriteClassPathXmlApplicationContext("spring.xml");
User user = (User) handwriteClassPathXmlApplicationContext.getBean("person");
System.out.println(user);
}
}
输出结果如下:
Disconnected from the target VM, address: '127.0.0.1:56717', transport: 'socket'
wxtest.tezxt.User@14bf9759
Process finished with exit code 0
以上就是简单实现通过解析xml,最后通过反射创建出相应的对象的。