3.7 spring-property 子元素的使用与解析
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 子元素的使用与解析的更多相关文章
- 3.6 spring-construction-arg 子元素的使用与解析
对于构造函数子元素是非常常用的. 相信大家也一定不陌生, 举个小例子: public class Animal { public String type; public int age; /** * ...
- 3.5 spring-replaced-method 子元素的使用与解析
1.replaced-method 子元素 方法替换: 可以在运行时用新的方法替换现有的方法,与之前的 look-up不同的是replace-method 不但可以动态地替换返回的实体bean,而且可 ...
- 3.4 spring- lookup-method 子元素的使用与解析
1. lookup-method的应用: 1.1 子元素lookup-method 似乎不是很常用,但是在某些时候他的确是非常有用的属性,通常我们称它为 "获取器注入" . 引用 ...
- 3.8 spring-qualifier 子元素的使用与解析
对于 qualifier 子元素,我们接触的更多的是注解形式,在使用Spring 自动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个.当找不到一个匹配的 Bean 时, S ...
- 3.3 spring-meta子元素的使用与解析
1. meta元素的使用 在解析元数据的分析之前,我们先回顾一下 meta属性的使用: <bean id="car" class="test.CarFactoryB ...
- Spring 系列教程之默认标签的解析
Spring 系列教程之默认标签的解析 之前提到过 Spring 中的标签包括默认标签和自定义标签两种,而两种标签的用法以及解析方式存在着很大的不同,本章节重点带领读者详细分析默认标签的解析过程. 默 ...
- Spring框架之beans源码完全解析
导读:Spring可以说是Java企业开发里最重要的技术.而Spring两大核心IOC(Inversion of Control控制反转)和AOP(Aspect Oriented Programmin ...
- spring bean属性及子元素使用总结
spring bean属性及子元素使用总结 2016-08-03 00:00 97人阅读 评论(0) 收藏 举报 分类: Spring&SpringMVC(17) 版权声明:本文为博主原创 ...
- Spring 配置文件中 元素 属性 说明
<beans /> 元素 该元素是根元素.<bean /> 元素的属性 default-init // 是否开启懒加载.默认为 false default-dependency ...
随机推荐
- Java之绘制实例
前面已经介绍过绘制方法. 弧形的绘制: package com.caiduping; import java.awt.Graphics; import javax.swing.JFrame; impo ...
- JS调用iframe方式实现Web区域打印页面内容
1.程序说明 1) 此程序可以实现选择页面中的区域进行打印,以iframe方式进行打印: 2) 与原生态的print() 区别在于,取消打印页面后可以完整保留当前访问页面的内容. 2.代码部分 1) ...
- RSS订阅推荐
科技新闻 虎嗅网 http://www.huxiu.com/ 科技博客的新生力量,文章以观点鲜明出名: 36氪 http://www.36kr.com/ 科技博客,关注创业,可以免费发表创业公司新闻 ...
- JavaScript的语法规则
JavaScript的语法规则 JavaScript区分大小写 JavaScript脚本程序须嵌入在HTML文件中 JavaScript脚本程序中不能包含HTML标记代码 每行写一条脚本语句 语句末尾 ...
- Codevs 5126 推销员 2015年NOIP全国联赛普及组
5126 推销员 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 阿明是一名推销员,他奉命到螺丝街推销他们公司的产品.螺丝街是一条死 ...
- 阿里云 centos 环境配置与 django 部署
1. 免密码登陆 # 本机生成密钥, 并将 pub 复制到阿里云服务器上 $ ssh-keygen -t rsa -P '' # -P表示密码,-P '' 就表示空密码 $ scp ~/.ssh/FI ...
- js function定义函数的4种方法
js function定义函数的4种方法 1.最基本的作为一个本本分分的函数声明使用. 复制代码代码如下: 复制代码代码如下: function func(){} 或 var func=functio ...
- 专家解说IT行业存在哪些安全风险
本人为原创作品:e良师益友 ,转载是并且注明 网络带动了IT行业的发展,同时也带来了安全风险,国外的专家分析2014年IT行业存在的11个安全隐患,随着越来越多技术的不断开发,为方便人们记忆账号,产生 ...
- 第三章 用SDK编译出第一个在Linux下的软件界面
第三章 用SDK编译出第一个在Linux下的软件界面 先创建一个工程目录“mkdir project1”,进入目录,创建main.cpp文件,编写代码如下: 代码内容暂时可以先不理解,先让程序跑起来再 ...
- C#利用开源软件ffMpeg截取视频图片
#region 从视频画面中截取一帧画面为图片 /// <summary> /// 从视频画面中截取一帧画面为图片 /// </summary> /// <param n ...