Spring核心学习(4)从XML中读取BeanDefinition-将代码变成配置

来源:互联网 发布:炉石传说卡牌数据库 编辑:程序博客网 时间:2024/06/06 20:57

前导:开始学习Spring核心思想,通过一个山寨精简版Spring代码结合学习。


内容:1. BeanDefinitionReader-配置读取者。 2. XmlBeanDefinitionReader-从XML中读取配置。 3. Resource-定位资源文件。这次将Bean的配置信息都放到了XML里,所以这里会有一个XML文件的读取,我们通过XmlBeanDefinitionReader将XML中的信息组装好成BeanDefinition放到一个Map里,这样我们就能真正做到像Spring那样靠配置文件来组装Bean。


重复的代码不再列出

BeanDefinition:

public class BeanDefinition {private Object bean;private Class beanClass;private String beanClassName;private PropertyValues propertyValues = new PropertyValues();public BeanDefinition() {}public Object getBean() {return bean;}public void setBean(Object bean) {this.bean = bean;}public Class getBeanClass() {return beanClass;}public void setBeanClass(Class beanClass) {this.beanClass = beanClass;}public String getBeanClassName() {return beanClassName;}public void setBeanClassName(String beanClassName) {this.beanClassName = beanClassName;try {this.beanClass = Class.forName(beanClassName);} catch (ClassNotFoundException e) {e.printStackTrace();} }public PropertyValues getPropertyValues() {return propertyValues;}public void setPropertyValues(PropertyValues propertyValues) {this.propertyValues = propertyValues;}}

Resource:

/** * Resource是spring内部定位资源接口 * @author acer */public interface Resource {InputStream getInputStream() throws IOException;}
ResourceLoader:

public class ResourceLoader {public Resource getResource(String location) {URL resource = this.getClass().getClassLoader().getResource(location);return new UrlResource(resource);}}
UrlResource:

public class UrlResource implements Resource{private final URL url;public UrlResource(URL url) {this.url = url;}@Overridepublic InputStream getInputStream() throws IOException {URLConnection urlConnection = url.openConnection();urlConnection.connect();return urlConnection.getInputStream();}}
BeanDefinitionReader:

/** * 从配置中读取BeanDefinitionReader * @author acer * */public interface BeanDefinitionReader {void loadBeanDefinitions(String location) throws Exception;}
AbstractBeanDefinitionReader:

/** * 从配置中读取BeanDefinitionReader * @author acer * */public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader{private Map<String, BeanDefinition> registry;private ResourceLoader resourceLoader;protected AbstractBeanDefinitionReader(ResourceLoader resourceLoader) {this.registry = new HashMap<String, BeanDefinition>();this.resourceLoader = resourceLoader;} public Map<String, BeanDefinition> getRegistry() {return this.registry;}public ResourceLoader getResourceLoader() {return resourceLoader;}}

XmlBeanDefinitionReader:

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

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

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="step4.test.HelloWorldService">        <property name="text" value="Hello World! from step4!"></property>    </bean></beans>



0 0
原创粉丝点击