spring源码附录(5)解析子元素constructor-arg
来源:互联网 发布:mac怎么登陆千牛 编辑:程序博客网 时间:2024/05/16 16:18
一、基本使用
public class Animal { public String type; public int age; /** * @param type * @param age */ public Animal(String type, int age) { super(); this.type = type; this.age = age; } /* * (non-Javadoc) * * @see java.lang.Object#toString() */ @Override public String toString() { return "Animal [type=" + type + ", age=" + age + "]"; }}
<?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.constructor.Animal"> <constructor-arg index="0" value="cat" type="String"></constructor-arg> <constructor-arg value="100" ></constructor-arg> </bean></beans>
public class Main { public static String XML_PATH = "test\\constructor\\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解析
对于construction-arg 子元素的解析,Spring 是通过 BeanDefinitionParserDelegate. parseConstructorArgElements(Element beanEle, BeanDefinition bd); 方法来实现的
/** * Parse constructor-arg sub-elements of the given bean element. */ public void parseConstructorArgElements(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, CONSTRUCTOR_ARG_ELEMENT)) { // parseConstructorArgElement parseConstructorArgElement((Element) node, bd); } } }
追踪下去如下:
从上面的代码上看,对构造函数中属性的解析,经历了以下几个过程:
1. 略过description 和 meta
2. 提取 ref ,value 属性,并验证其合法性,
3. ref 属性的处理,使用 RuntimeBeanReference 封装
4. Value 属性的处理 , 使用TypedStringValue封装
5. 子属性的处理 如
<constructor-arg> <map> <entry key = "key" value = "value"></entry> </map></constructor-arg>
而对于子元素,则交给 parsePropertySubElement 方法来实现对各种子元素进行分类处理
public Object parsePropertySubElement(Element ele, BeanDefinition bd) { return parsePropertySubElement(ele, bd, null);}
/** * Parse a value, ref or collection sub-element of a property or constructor-arg * element. * * @param ele subelement of property element; we don't know which yet * @param defaultValueType the default type (class name) for any {@code <value>} * tag that might be created */ public Object parsePropertySubElement(Element ele, BeanDefinition bd, String defaultValueType) { if (!isDefaultNamespace(ele)) { return parseNestedCustomElement(ele, bd); } else if (nodeNameEquals(ele, BEAN_ELEMENT)) { BeanDefinitionHolder nestedBd = parseBeanDefinitionElement(ele, bd); if (nestedBd != null) { nestedBd = decorateBeanDefinitionIfRequired(ele, nestedBd, bd); } return nestedBd; } else if (nodeNameEquals(ele, REF_ELEMENT)) { // A generic reference to any name of any bean. String refName = ele.getAttribute(BEAN_REF_ATTRIBUTE); boolean toParent = false; if (!StringUtils.hasLength(refName)) { // A reference to the id of another bean in the same XML file. // 解析本地资源 refName = ele.getAttribute(LOCAL_REF_ATTRIBUTE); if (!StringUtils.hasLength(refName)) { // A reference to the id of another bean in a parent context. // 解析父类资源 refName = ele.getAttribute(PARENT_REF_ATTRIBUTE); toParent = true; if (!StringUtils.hasLength(refName)) { error("'bean', 'local' or 'parent' is required for <ref> element", ele); return null; } } } if (!StringUtils.hasText(refName)) { error("<ref> element contains empty target attribute", ele); return null; } RuntimeBeanReference ref = new RuntimeBeanReference(refName, toParent); ref.setSource(extractSource(ele)); return ref; } // 对idref 的处理 else if (nodeNameEquals(ele, IDREF_ELEMENT)) { return parseIdRefElement(ele); } // 对value 的处理 else if (nodeNameEquals(ele, VALUE_ELEMENT)) { return parseValueElement(ele, defaultValueType); } // 对 null 的处理 else if (nodeNameEquals(ele, NULL_ELEMENT)) { // It's a distinguished null value. Let's wrap it in a TypedStringValue // object in order to preserve the source location. TypedStringValue nullHolder = new TypedStringValue(null); nullHolder.setSource(extractSource(ele)); return nullHolder; } // 对array 的处理 else if (nodeNameEquals(ele, ARRAY_ELEMENT)) { return parseArrayElement(ele, bd); } // 对list 的处理 else if (nodeNameEquals(ele, LIST_ELEMENT)) { return parseListElement(ele, bd); } // 对set 的处理 else if (nodeNameEquals(ele, SET_ELEMENT)) { return parseSetElement(ele, bd); } // 对map 的处理 else if (nodeNameEquals(ele, MAP_ELEMENT)) { return parseMapElement(ele, bd); } // 对props 的处理 else if (nodeNameEquals(ele, PROPS_ELEMENT)) { return parsePropsElement(ele); } else { error("Unknown property sub-element: [" + ele.getNodeName() + "]", ele); return null; } }
0 0
- spring源码附录(5)解析子元素constructor-arg
- Spring解析子元素constructor-arg
- spring源码附录(6)解析子元素property
- spring - constructor-arg
- Spring Ioc 技术(constructor-arg )
- Spring Ioc 技术(constructor-arg )
- spring - constructor-arg 的使用
- spring - constructor-arg 的使用
- Spring框架 constructor-arg注入
- Spring constructor-arg、c、p
- Spring : constructor-arg property 注入
- spring源码附录(8)import、beans标签的解析
- spring源码附录(3)spring bean子标签 loopup-method、replaced-method基本用法
- spring源码解析之bean的子元素
- spring 的applicationContext.xml中的constructor-arg
- Java Spring Tutorial -- constructor-arg标签
- spring - property和constructor-arg的使用
- spring - property和constructor-arg的使用
- socket编程入门(一)
- 【LeetCode】50. Pow(x, n)
- swf逆向调试
- 知识点2:阐述面向对象的三大特征
- .class 概述 jvm
- spring源码附录(5)解析子元素constructor-arg
- 手推adaBoost
- Linux指令
- 湖北民族学院oj 1775(贪心)(杭电1009) 之 FatMouse's Trade
- 关于Linux下源码安装
- mysql索引知识笔记
- 如何使用搜索引擎
- MyBatis概述
- 类型萃取