1.0 Property子元素的使用

  property 子元素是再常用不过的了, 在看Spring源码之前,我们先看看它的使用方法,

1. 实例类如下:

 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如下,

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

控制台输出的结果为

Animal [type=cat, age=[1, 2, 3], sell={blue=111, red=22}]

2.0 Spring具体的解析过程为:

  2.1

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

  2.2

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

  2.3 然后又回到parsePropertyValue 方法了

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

这里之前构造函数的解析那里已经讲得很详细了,这里不多做解释,不同的是返回值使用PropertyValue 封装,并且记录在BeanDefinition 的 propertyValues属性当中.

3.7 spring-property 子元素的使用与解析的更多相关文章

  1. 3.6 spring-construction-arg 子元素的使用与解析

    对于构造函数子元素是非常常用的. 相信大家也一定不陌生, 举个小例子: public class Animal { public String type; public int age; /** * ...

  2. 3.5 spring-replaced-method 子元素的使用与解析

    1.replaced-method 子元素 方法替换: 可以在运行时用新的方法替换现有的方法,与之前的 look-up不同的是replace-method 不但可以动态地替换返回的实体bean,而且可 ...

  3. 3.4 spring- lookup-method 子元素的使用与解析

    1. lookup-method的应用: 1.1 子元素lookup-method 似乎不是很常用,但是在某些时候他的确是非常有用的属性,通常我们称它为 "获取器注入" . 引用 ...

  4. 3.8 spring-qualifier 子元素的使用与解析

      对于 qualifier 子元素,我们接触的更多的是注解形式,在使用Spring 自动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个.当找不到一个匹配的 Bean 时, S ...

  5. 3.3 spring-meta子元素的使用与解析

    1. meta元素的使用 在解析元数据的分析之前,我们先回顾一下 meta属性的使用: <bean id="car" class="test.CarFactoryB ...

  6. Spring 系列教程之默认标签的解析

    Spring 系列教程之默认标签的解析 之前提到过 Spring 中的标签包括默认标签和自定义标签两种,而两种标签的用法以及解析方式存在着很大的不同,本章节重点带领读者详细分析默认标签的解析过程. 默 ...

  7. Spring框架之beans源码完全解析

    导读:Spring可以说是Java企业开发里最重要的技术.而Spring两大核心IOC(Inversion of Control控制反转)和AOP(Aspect Oriented Programmin ...

  8. spring bean属性及子元素使用总结

    spring bean属性及子元素使用总结 2016-08-03 00:00 97人阅读 评论(0) 收藏 举报  分类: Spring&SpringMVC(17)  版权声明:本文为博主原创 ...

  9. Spring 配置文件中 元素 属性 说明

    <beans /> 元素 该元素是根元素.<bean /> 元素的属性 default-init // 是否开启懒加载.默认为 false default-dependency ...

随机推荐

  1. 锋利的jQuery第2版学习笔记4、5章

    第4章,jQuery中的事件和动画 注意:使用的jQuery版本为1.7.1 jQuery中的事件 JavaScript中通常使用window.onload方法,jQuery中使用$(document ...

  2. 从零单排Linux – 2 – 目录权限

    从零单排Linux – 2 – 目录权限 1.sync 讲内存数据跟新到硬盘中 2.执行等级init a: run level 0:关机 b: run level 3:纯命令模式 c:run leve ...

  3. Android的ListView分页功能

    一.功能分析----ListView“加载更多”,功能如下图所示: 这个效果是当你上拉拖动页面时(注意有区别于下拉刷新),页面提示正在加载,2秒后显示留言更多内容:具体功能知道那我就来讲解下如何实现这 ...

  4. 配置tomcat免安装版服务器

    一.首先,确保服务器已经安装java环境,没有tomcat的可以到这里下载 http://tomcat.apache.org/ 二.解压下载的压缩包,我是解压到D盘根目录下的.记住这个目录,后面会用到 ...

  5. C# Winform AutoScaleMode属性

    属性的用法: None : 禁用自动缩放.(默认时) Font :根据类使用的字体(通常为系统字体)的维度控制缩放. Dpi : 根据显示分辨率控制缩放.常用分辨率为 96 和 120 DPI. In ...

  6. C#全屏随机位置显示图片的小程序

    想法:将屏幕截图作为程序背景图,在之上弹出提示窗口,选择确定后进行定时图片随机位置显示.(支持ESC键退出) 需要添加的控件:Timer 需要修改的Form1属性为下图红色区域: 资源文件的添加:添加 ...

  7. Linux multiple open a device

    Linux multiple open a device a device = /dev/wiegand Linux在多次打开同一个设备(/dev/wiegand)的时候,打开结果都是成功,但是在用w ...

  8. bind()实现

    bind()函数是在 ECMA-262 第五版才被加入:它可能无法在所有浏览器上运行.这就需要我们自己实现bind()函数了 简单实现bind()方法: Function.prototype.bind ...

  9. WCF 初识(一)

    WCF的前世今生 在.NETFramework 2.0以及前版本中,微软发展了Web Service(SOAP with HTTP communication),.NET Remoting(TCP/H ...

  10. C# Json数据反序列化为Dictionary并根据关键字获取指定值1

    Json数据: { "dataSet": { "header": { "returnCode": "0", " ...