设计模式之4.2 Spring bean容器以及怎么从xml当中读取配置信息

来源:互联网 发布:淘宝版阿里旺旺下载 编辑:程序博客网 时间:2024/04/30 15:45

毫无疑问,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;

 

//jdomxpath结合。

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容器,需要把ido对象放到这个容器当中,这个就是springbean容器

    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,解析他们的idclass

         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();

          //ido对象,都添加到容器当中,这里是键值对,也就是说是一个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,这里的idv

       //我们在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,动态代理。下次继续。

 

祝大家新年快乐,万事如意,事事顺心!!

 

原创粉丝点击