您的位置:首页 > 编程语言 > Java开发

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

2017-06-02 20:01 519 查看
      在上两篇博客中,采用的是通过给定的包名和类名使用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);
}

@Override
public 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);
// 解析bean
registerBeanDefinitions(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.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://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 {

@Test
public void test() throws Exception {
// 1.读取配置
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(new ResourceLoader());
xmlBeanDefinitionReader.loadBeanDefinitions("tinyioc.xml");

// 2.初始化BeanFactory并注册bean
BeanFactory beanFactory = new AutowireCapableBeanFactory();
for (Map.Entry<String, BeanDefinition> beanDefinitionEntry : xmlBeanDefinitionReader.getRegistry().entrySet()) {
beanFactory.registerBeanDefinition(beanDefinitionEntry.getKey(), beanDefinitionEntry.getValue());
}

// 3.获取bean
HelloWorldService helloWorldService = (HelloWorldService) beanFactory.getBean("helloWorldService");
helloWorldService.helloWorld();

}
}


   

         step4的过程中,通过类图,明显的感觉到类的数量明显增多。其最终都是围绕xml解析工作的。该工程中,相比于step3中给出的包名和类名动态加载类,先step4是通过xml读取配置,即我们需要做的就是xml文件的配置而已,其它的工作都已经封装在了解析xml文件的功能中。这样的好处是什么?提升我们的灵活可配置性,如果通过包名和类名动态加载类,那么这个类就不能轻易的更换包名称,同样可称之为“代码写死”,so,现在代码虽然多了,但是,我们需要做得却更方便了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: