spring源码附录(6)解析子元素property

来源:互联网 发布:软件架构设计的软件 编辑:程序博客网 时间:2024/05/24 01:14

对于子元素constructor-arg的解析看这里:http://blog.csdn.net/disiwei1012/article/details/70500005

一、基本用法

public class Animal {    public String type;    public Set<Integer> age;    private Map<String, Integer> sell;    public Animal() {    }    /**     * @return the type     */    public String getType() {        return type;    }    /**     * @param type the type to set     */    public void setType(String type) {        this.type = type;    }    /**     * @return the age     */    public Set<Integer> getAge() {        return age;    }    /**     * @param age the age to set     */    public void setAge(Set<Integer> age) {        this.age = age;    }    /**     * @return the sell     */    public Map<String, Integer> getSell() {        return sell;    }    /**     * @param sell the sell to set     */    public void setSell(Map<String, Integer> sell) {        this.sell = sell;    }    /*     * (non-Javadoc)     *      * @see java.lang.Object#toString()     */    @Override    public String toString() {        return "Animal [type=" + type + ", age=" + age + ", sell=" + sell + "]";    }}
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">    <bean id="animal" class="test.property.Animal">        <property name="type" value="cat"></property>        <property name="age">            <set>                <value>1</value>                <value>2</value>                <value>3</value>            </set>        </property>        <property name="sell">            <map>                <entry key="blue" value="111"></entry>                <entry key="red" value="22"></entry>            </map>        </property>    </bean></beans>

测试:

public class Main {    public static String XML_PATH = "test\\property\\applicationContxt.xml";    public static void main(String[] args) {        try {            Resource resource = new ClassPathResource(XML_PATH);            XmlBeanFactory beanFactory = new XmlBeanFactory(resource);            Animal bean = (Animal) beanFactory.getBean("animal");            System.out.println(bean);        }        catch (Exception e) {            e.printStackTrace();        }    }}

二、spring解析

/**     * Parse property sub-elements of the given bean element.     */    public void parsePropertyElements(Element beanEle, BeanDefinition bd) {        NodeList nl = beanEle.getChildNodes();        for (int i = 0; i < nl.getLength(); i++) {            Node node = nl.item(i);            if (isCandidateElement(node) && nodeNameEquals(node, PROPERTY_ELEMENT)) {                // 这里进去                parsePropertyElement((Element) node, bd);            }        }    }
/**     * Parse a property element.     */    public void parsePropertyElement(Element ele, BeanDefinition bd) {        // 获取配置文件中name 的值        String propertyName = ele.getAttribute(NAME_ATTRIBUTE);        if (!StringUtils.hasLength(propertyName)) {            error("Tag 'property' must have a 'name' attribute", ele);            return;        }        this.parseState.push(new PropertyEntry(propertyName));        try {            // 不容许多次对同一属性配置            if (bd.getPropertyValues().contains(propertyName)) {                error("Multiple 'property' definitions for property '" + propertyName                        + "'", ele);                return;            }            Object val = parsePropertyValue(ele, bd, propertyName);            PropertyValue pv = new PropertyValue(propertyName, val);            parseMetaElements(ele, pv);            pv.setSource(extractSource(ele));            bd.getPropertyValues().addPropertyValue(pv);        }        finally {            this.parseState.pop();        }    }
public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName) {        String elementName = (propertyName != null) ? "<property> element for property '"                + propertyName + "'" : "<constructor-arg> element";        // Should only have one child element: ref, value, list, etc.        // 应该只有一个子元素:REF,值,列表等。        NodeList nl = ele.getChildNodes();        Element subElement = null;        for (int i = 0; i < nl.getLength(); i++) {            Node node = nl.item(i);            // 对应的description 或者meta不处理            if (node instanceof Element && !nodeNameEquals(node, DESCRIPTION_ELEMENT)                    && !nodeNameEquals(node, META_ELEMENT)) {                // Child element is what we're looking for.                if (subElement != null) {                    error(elementName + " must not contain more than one sub-element",                            ele);                }                else {                    subElement = (Element) node;                }            }        }        // 解析 ref        boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE);        // 解析 value        boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE);        if ((hasRefAttribute && hasValueAttribute)                || ((hasRefAttribute || hasValueAttribute) && subElement != null)) {            /*             * 1.不能同时有ref 又有 value 2.不能存在ref 或者 value 又有子元素             */            error(elementName                    + " is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element",                    ele);        }        if (hasRefAttribute) {            String refName = ele.getAttribute(REF_ATTRIBUTE);            if (!StringUtils.hasText(refName)) {                error(elementName + " contains empty 'ref' attribute", ele);            }            // ref 属性的处理 , 使用RuntimeBeanReference封装对应的ref名称            RuntimeBeanReference ref = new RuntimeBeanReference(refName);            ref.setSource(extractSource(ele));            return ref;        }        else if (hasValueAttribute) {            // Value 属性的处理 , 使用TypedStringValue封装对应的            TypedStringValue valueHolder = new TypedStringValue(                    ele.getAttribute(VALUE_ATTRIBUTE));            valueHolder.setSource(extractSource(ele));            return valueHolder;        }        else if (subElement != null) {            // 解析子元素            return parsePropertySubElement(subElement, bd);        }        else {            // Neither child element nor "ref" or "value" attribute found.            // 对于没有ref 也没有子元素的,Spring只好丢出异常            error(elementName + " must specify a ref or value", ele);            return null;        }    }
0 0
原创粉丝点击