Spring Property
- Author: HuiFer
源码阅读仓库: SourceHot-spring
相关类
org.springframework.beans.PropertyValuesorg.springframework.beans.PropertyValueorg.springframework.beans.MutablePropertyValues
类图如下

在 Spring IoC 中,非 Web 工程,使用 xml 或者注解进行配置主要使用到的是
PropertyValues,PropertyValue,MutablePropertyValues三个其中
PropertyValues是继承迭代器,具体实现在MutablePropertyValues他们处理的对象是PropertyValues关系就是这样.
开始类的解析了
PropertyValue
org.springframework.beans.PropertyValue类图

这个类暂时只关注两个属性
- name: 属性名称
- value: 属性值
对应标签
<property name="age" value="30"/>属性值一一对应填入.
MutablePropertyValues
org.springframework.beans.MutablePropertyValues属性
propertyValueList:属性列表, key:参数名称,value:具体数据processedProperties: 已经处理的属性名称converted: 是否转换
public class MutablePropertyValues implements PropertyValues, Serializable {/*** 属性列表, key:参数名称,value:具体数据*/private final List<PropertyValue> propertyValueList;/*** 已经处理的属性名称*/@Nullableprivate Set<String> processedProperties;/*** 是否转换*/private volatile boolean converted = false;}
构造器
MutablePropertyValues的一个构造器. 其他构造器的方式原理实现差不多. 核心是将构造参数转换成PropertyValue对象在放入propertyValueList中
public MutablePropertyValues(@Nullable PropertyValues original) {// We can optimize this because it's all new:// There is no replacement of existing property values.if (original != null) {// 从列表中获取所有可能指PropertyValue[] pvs = original.getPropertyValues();this.propertyValueList = new ArrayList<>(pvs.length);for (PropertyValue pv : pvs) {// 循环插入 property valuesthis.propertyValueList.add(new PropertyValue(pv));}}else {this.propertyValueList = new ArrayList<>(0);}}
PropertyValue 的构造方法
public PropertyValue(PropertyValue original) {Assert.notNull(original, "Original must not be null");this.name = original.getName();this.value = original.getValue();this.optional = original.isOptional();this.converted = original.converted;this.convertedValue = original.convertedValue;this.conversionNecessary = original.conversionNecessary;this.resolvedTokens = original.resolvedTokens;setSource(original.getSource());copyAttributesFrom(original);}
- 除了最后一行是一个复杂调用. 前面几行代码都是属性赋值操作.
- 最后一行代码会调用
AttributeAccessor接口上的方法.
- 最后一行代码会调用
AttributeAccessor
org.springframework.core.AttributeAccessor完整的方法列表及作用注释
public interface AttributeAccessor {/*** 设置属性值* @param name 属性值名称* @param value 属性值*/void setAttribute(String name, @Nullable Object value);/*** 通过属性名称获取属性值** @param name 属性值名称* @return 属性值*/@NullableObject getAttribute(String name);/*** 移除指定属性名称的值,返回移除的属性值** @param name 属性值名称* @return 移除的属性值*/@NullableObject removeAttribute(String name);/*** 是否包含属性名称* @param 属性名称*/boolean hasAttribute(String name);/*** 属性名称列表*/String[] attributeNames();}
- 回到
org.springframework.core.AttributeAccessorSupport#copyAttributesFrom方法
protected void copyAttributesFrom(AttributeAccessor source) {Assert.notNull(source, "Source must not be null");// 获取属性名称列表String[] attributeNames = source.attributeNames();// 循环属性名称列表for (String attributeName : attributeNames) {// 设置属性// name: 属性名称,value: 从入参中获取属性名称对应的属性值setAttribute(attributeName, source.getAttribute(attributeName));}}
setAttribute
- 一个 map 操作
@Overridepublic void setAttribute(String name, @Nullable Object value) {Assert.notNull(name, "Name must not be null");if (value != null) {this.attributes.put(name, value);}else {removeAttribute(name);}}
addPropertyValue
org.springframework.beans.MutablePropertyValues#addPropertyValue(org.springframework.beans.PropertyValue)
public MutablePropertyValues addPropertyValue(PropertyValue pv) {// 循环获取 属性对象for (int i = 0; i < this.propertyValueList.size(); i++) {// 正在处理的 属性对象PropertyValue currentPv = this.propertyValueList.get(i);// 正在处理的属性对象名称和添加的属性对象名称比较// 如果相同会做一个合并操作if (currentPv.getName().equals(pv.getName())) {// 合并属性pv = mergeIfRequired(pv, currentPv);// 重新设置setPropertyValueAt(pv, i);return this;}}// 放入 list 集合this.propertyValueList.add(pv);return this;}
mergeIfRequired
org.springframework.beans.MutablePropertyValues#mergeIfRequired这段代码会取舍新老数据.
- 如果是
Mergeable类型会做合并操作 - 直接返回新数据
- 如果是
private PropertyValue mergeIfRequired(PropertyValue newPv, PropertyValue currentPv) {Object value = newPv.getValue();if (value instanceof Mergeable) {Mergeable mergeable = (Mergeable) value;if (mergeable.isMergeEnabled()) {// 获取合并的结果,放入对象Object merged = mergeable.merge(currentPv.getValue());// 创建新的 属性对象return new PropertyValue(newPv.getName(), merged);}}return newPv;}
配合测试代码,跟容易看懂.
@Testpublic void testAddOrOverride() {MutablePropertyValues pvs = new MutablePropertyValues();pvs.addPropertyValue(new PropertyValue("forname", "Tony"));pvs.addPropertyValue(new PropertyValue("surname", "Blair"));pvs.addPropertyValue(new PropertyValue("age", "50"));doTestTony(pvs);PropertyValue addedPv = new PropertyValue("rod", "Rod");pvs.addPropertyValue(addedPv);assertThat(pvs.getPropertyValue("rod").equals(addedPv)).isTrue();PropertyValue changedPv = new PropertyValue("forname", "Greg");pvs.addPropertyValue(changedPv);assertThat(pvs.getPropertyValue("forname").equals(changedPv)).isTrue();}
Mergeable
新的接口Mergeable
org.springframework.beans.Mergeable
public interface Mergeable {/*** 是否需要合并*/boolean isMergeEnabled();/*** 合并方法*/Object merge(@Nullable Object parent);}

- 看一下 List 怎么实现
merge
@Override@SuppressWarnings("unchecked")public List<E> merge(@Nullable Object parent) {if (!this.mergeEnabled) {throw new IllegalStateException("Not allowed to merge when the 'mergeEnabled' property is set to 'false'");}if (parent == null) {return this;}if (!(parent instanceof List)) {throw new IllegalArgumentException("Cannot merge with object of type [" + parent.getClass() + "]");}List<E> merged = new ManagedList<>();merged.addAll((List<E>) parent);merged.addAll(this);return merged;}
- 在 list 视线中就是讲两个结果合并. 事实上其他的几个都是这个操作. 这里就不贴所有的代码了
