毫无疑问,spring是从XML来读取配置信息的。
前面写过,在java当中读取XML配置信息的方式有四种。
分别是:
DOM(JAXP Crimson 解析器)
接着是 SAX
然后是 JDOM
最后是 DOM4J
我们先来看使用JDOM从XML当中读取配置信息的方式:
JDOM一般和xpath结合使用。
来看看IBM一篇关于JDOM和XPATH结合编程的指南。
http://www.ibm.com/developerworks/cn/xml/x-jdom/
文章我就不引用了。
首先下载jdom,并把需要所有的包引入到当前的project当中。
直接写我们调试成功能运行的程序:
先看看xml文件(这个文件我没有进行任何的改变):
<?xmlversion="1.0"encoding="UTF-8"?>
//特定的xml文件。
<HD>
<diskname="C">
<capacity>8G</capacity>
<directories>200</directories>
<files>1580</files>
</disk>
<diskname="D">
<capacity>10G</capacity>
<directories>500</directories>
<files>3000</files>
</disk>
</HD>
再来看java文件:
import java.util.*;
import org.jdom.*;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;
//jdom和xpath结合。
publicclass Sample2 {
publicstaticvoid main(String[] args)throws Exception {
SAXBuilder sb = new SAXBuilder();
//找到文件的位置,整个文档当成一个对象。
//原例子里面是使用的是绝对路径,我们采用从stream当中定位,换句话说还是从classpath当中找。
Document doc = sb.build(Sample2.class.getClassLoader().getResourceAsStream("sample.xml"));
//root是根对象。
Element root = doc.getRootElement();
//我们添加了一些输出信息
System.out.println(root);
//通过xpath拿到节点"/HD/disk"
List list = XPath.selectNodes(root,"/HD/disk");
//我们添加了一些输出信息
System.out.println(list.size());
for (int i = 0; i > list.size(); i++) {
Element disk_element = (Element)list.get(i);
String name =disk_element.getAttributeValue("name");
String capacity = ( (Text)XPath.selectSingleNode(disk_element,
"//disk[@name='" + name +"']/capacity/text()")).getTextNormalize();
String directories = ( (Text) XPath.selectSingleNode(disk_element,
"//disk[@name='" + name +"']/directories/text()")).getTextNormalize();
String files = ( (Text)XPath.selectSingleNode(disk_element,
"//disk[@name='" + name +"']/files/text()")).getTextNormalize();
System.out.println("磁盘信息:");
System.out.println("分区盘符:" + name);
System.out.println("分区容量:" + capacity);
System.out.println("目录数:" + directories);
System.out.println("文件数:" + files);
System.out.println("-----------------------------------");
}
}
}
那么我们现在就可以模拟spring的bean容器了。注意这里说的是bean容器,不是bean工厂。
首先在我们自己的项目当中,也把jdom所需的所有的类添加进去。
先看我们的xml文件:
<?xmlversion="1.0"encoding="UTF-8"?>
<beans>
<beanid="v"class="com.bjsxt.spring.factory.Train">
</bean>
<!-- //v=com.bjsxt.spring.factory.Car -->
</beans>
再看我们访问xml的类:
package com.bjsxt.spring.factory;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//使用了jdom,所以需要这些包
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;
//本类从BeanFactory当中继承,所以是实现了bean工厂
publicclass ClassPathXmlApplicationContextimplementsBeanFactory {
//定义了一个map容器,需要把id和o对象放到这个容器当中,这个就是spring的bean容器
private Map<String, Object>container = new HashMap<String, Object>();
//构造方法,当中传进来的参数是文件名,这个文件名就是要解析的xml文件名
public ClassPathXmlApplicationContext(String fileName)throws Exception{
SAXBuilder sb = new SAXBuilder();
//把filename传递过来,从classpath当中找到文件信息
Document doc =sb.build(this.getClass().getClassLoader()
.getResourceAsStream(fileName));
//root节点
Element root =doc.getRootElement();
//从beans/bean开始读,注意看xpath的使用
List list =XPath.selectNodes(root,"/beans/bean");
System.out.println(list.size());
//找到beans当中的每个bean,解析他们的id和class
for (int i = 0; i <list.size(); i++) {
//每个element都是一个bean,每个bean都是一个类。
Element bean =(Element) list.get(i);
//id就是相当于我们原来的v
String id =bean.getAttributeValue("id");
//class就是我们原来的值,也就是类的名字。
String clazz =bean.getAttributeValue("class");
//得到类的名字以后,就可以通过反射的Class.forName(clazz).newInstance()方法来得到对象
Object o = Class.forName(clazz).newInstance();
//把id和o对象,都添加到容器当中,这里是键值对,也就是说是一个map
container.put(id, o);
System.out.println(id +" " + clazz);
}
}
@Override
public Object getBean(String id) {
returncontainer.get(id);
}
}
最后来看使用者当中怎么调用:
package com.bjsxt.spring.factory;
import java.io.IOException;
import java.util.Properties;
publicclass Test {
/**
*@paramargs
*@throwsIOException
*/
publicstaticvoid main(String[] args)throws Exception {
//得到一个beanFactory对象,因为xml处理类是从beanFactory继承而来
BeanFactory f = new ClassPathXmlApplicationContext("com/bjsxt/spring/factory/applicationContext.xml");
//通过id找到相应的bean,这里的id是v
//我们在xml当中的信息是<bean id="v"class="com.bjsxt.spring.factory.Train">
Object o = f.getBean("v");
Moveable m = (Moveable)o;
m.run();
}
}
以上,就是spring当中bean容器!
Spring有两大特性,第一,beanFactory或者说bean 容器。
第二,AOP,动态代理。下次继续。
祝大家新年快乐,万事如意,事事顺心!!