《step4:tiny-spring-ioc学习四》——读取xml配置来初始化bean

来源:互联网 发布:手机淘宝联盟怎么用 编辑:程序博客网 时间:2024/06/05 00:22


      在上两篇博客中,采用的是通过给定的包名和类名使用java代码动态加载类,随着bean类的增加,貌似这样的容器管理bean方式就有些不大合适,所以,这篇博客是采用xml配置bean节点来完成初始化工作。

      这里的BeanDefinition只是一些配置,我们定义了BeanDefinitionReader初始化bean,它有一个实现是XmlBeanDefinitionReader。XmlBeanDefinitionReader类就是用来解析xml文件封装BeanDefinition对象的。所以,相比于之前的博客,这篇博客代码的变更主要便是xml的解析工作。

      依旧先看类图:



    时序图:



     由于代码量比较大,所以这里只是展示一些关键代码,全部代码请点击《下载》

      1·XmlBeanDefinitionReader类:

package us.codecraft.tinyioc.xml;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import us.codecraft.tinyioc.AbstractBeanDefinitionReader;import us.codecraft.tinyioc.BeanDefinition;import us.codecraft.tinyioc.PropertyValue;import us.codecraft.tinyioc.io.ResourceLoader;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import java.io.InputStream;/** * @author yihua.huang@dianping.com */public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {public XmlBeanDefinitionReader(ResourceLoader resourceLoader) {super(resourceLoader);}@Overridepublic void loadBeanDefinitions(String location) throws Exception {InputStream inputStream = getResourceLoader().getResource(location).getInputStream();doLoadBeanDefinitions(inputStream);}protected void doLoadBeanDefinitions(InputStream inputStream) throws Exception {DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder docBuilder = factory.newDocumentBuilder();Document doc = docBuilder.parse(inputStream);// 解析beanregisterBeanDefinitions(doc);inputStream.close();}public void registerBeanDefinitions(Document doc) {Element root = doc.getDocumentElement();parseBeanDefinitions(root);}protected void parseBeanDefinitions(Element root) {NodeList nl = root.getChildNodes();for (int i = 0; i < nl.getLength(); i++) {Node node = nl.item(i);if (node instanceof Element) {Element ele = (Element) node;processBeanDefinition(ele);}}}protected void processBeanDefinition(Element ele) {String name = ele.getAttribute("name");String className = ele.getAttribute("class");        BeanDefinition beanDefinition = new BeanDefinition();        processProperty(ele,beanDefinition);        beanDefinition.setBeanClassName(className);getRegistry().put(name, beanDefinition);}    private void processProperty(Element ele,BeanDefinition beanDefinition) {        NodeList propertyNode = ele.getElementsByTagName("property");        for (int i = 0; i < propertyNode.getLength(); i++) {            Node node = propertyNode.item(i);            if (node instanceof Element) {                Element propertyEle = (Element) node;                String name = propertyEle.getAttribute("name");                String value = propertyEle.getAttribute("value");                beanDefinition.getPropertyValues().addPropertyValue(new PropertyValue(name,value));            }        }    }}


      2·tinyioc.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">    <bean name="helloWorldService" class="us.codecraft.tinyioc.HelloWorldService">        <property name="text" value="Hello World!"></property>    </bean></beans>


      3·BeanFactoryTest测试类:

package us.codecraft.tinyioc;import org.junit.Test;import us.codecraft.tinyioc.factory.AutowireCapableBeanFactory;import us.codecraft.tinyioc.factory.BeanFactory;import us.codecraft.tinyioc.io.ResourceLoader;import us.codecraft.tinyioc.xml.XmlBeanDefinitionReader;import java.util.Map;/** * @author yihua.huang@dianping.com */public class BeanFactoryTest {@Testpublic void test() throws Exception {// 1.读取配置XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(new ResourceLoader());xmlBeanDefinitionReader.loadBeanDefinitions("tinyioc.xml");// 2.初始化BeanFactory并注册beanBeanFactory beanFactory = new AutowireCapableBeanFactory();for (Map.Entry<String, BeanDefinition> beanDefinitionEntry : xmlBeanDefinitionReader.getRegistry().entrySet()) {beanFactory.registerBeanDefinition(beanDefinitionEntry.getKey(), beanDefinitionEntry.getValue());}// 3.获取beanHelloWorldService helloWorldService = (HelloWorldService) beanFactory.getBean("helloWorldService");helloWorldService.helloWorld();}}

   

         step4的过程中,通过类图,明显的感觉到类的数量明显增多。其最终都是围绕xml解析工作的。该工程中,相比于step3中给出的包名和类名动态加载类,先step4是通过xml读取配置,即我们需要做的就是xml文件的配置而已,其它的工作都已经封装在了解析xml文件的功能中。这样的好处是什么?提升我们的灵活可配置性,如果通过包名和类名动态加载类,那么这个类就不能轻易的更换包名称,同样可称之为“代码写死”,so,现在代码虽然多了,但是,我们需要做得却更方便了。


阅读全文
0 0