Spring 系列目录(http://www.javashuo.com/article/p-hskusway-em.html)html
PropertyValue 和 PropertyValues 都位于 org.springframework.beans 包下,是 bean 属性键值对的封装,缓存了对 key-value 解析相关的信息,避免重复解析。java
AttributeAccessor
能够访问对象的属性或将属性附加到对象上。BeanMetadataElement
持有属性信息的对象。BeanMetadataAttributeAccessor
实现了 AttributeAccessor 和 BeanMetadataElement 两个接口,属性为 BeanMetadataAttribute 对象。PropertyValue
属性键值对。有一点不太明白 PropertyValue 表示一个属性键值对,PropertyValues 表示多个属性键值对,那 PropertyValue 为何还要继承 AttributeAccessor 接口,AttributeAccessor 能够对多个属性进行管理。spring
public interface AttributeAccessor { // 对属性进行增删改查 void setAttribute(String name, @Nullable Object value); Object getAttribute(String name); Object removeAttribute(String name); boolean hasAttribute(String name); String[] attributeNames(); }
AttributeAccessor 接口的实现类为 AttributeAccessorSupport,在这个类中维护一个 Map<String, Object> attributes = new LinkedHashMap<>()
,对属性进行增删改查。缓存
public interface BeanMetadataElement { Object getSource(); }
BeanMetadataAttributeAccessor 的实现了 AttributeAccessor 和 BeanMetadataElement 两个接口,内部维护的是 <propertyName, BeanMetadataAttribute> 键值对,BeanMetadataAttribute 是一个持有属性对和源的对象。ide
public class BeanMetadataAttribute implements BeanMetadataElement { // 属性 key - value private final String name; private final Object value; // 属性所属的对象 private Object source; }
PropertyValue 缓存了对 key-value 解析相关的信息,避免重复解析。如 AbstractNestablePropertyAccessor#processLocalProperty 进行属性注入时,会判断是否须要对属性值进行类型转换。相关字段以下:ui
// 1.1 属性名称 private final String name; // 1.1 属性值 private final Object value; // 2.1 属性值是否为 Optional private boolean optional = false; // 2.2 属性值是否已经进行了类型转换 private boolean converted = false; // 2.3 类型转换后的属性值 private Object convertedValue; // 3.1 属性值是否须要进行类型转换,若是转换先后对象都是同一个,说明不用转换 volatile Boolean conversionNecessary; // 3.2 缓存解析后的属性名称,如 attr['info']['name'] transient volatile Object resolvedTokens;
直接设置 convertedValue 值时 converted = true。this
public synchronized void setConvertedValue(@Nullable Object value) { this.converted = true; this.convertedValue = value; }
PropertyValues 表示多个属性键值对,接口以下:spa
public interface PropertyValues extends Iterable<PropertyValue> { // @since 5.1 default Iterator<PropertyValue> iterator() { return Arrays.asList(getPropertyValues()).iterator(); } PropertyValue[] getPropertyValues(); PropertyValue getPropertyValue(String propertyName); boolean contains(String propertyName); boolean isEmpty(); // old 和当前的对比,返回当前有而 old 没有的元素 PropertyValues changesSince(PropertyValues old); }
PropertyValues 的默认实现为 MutablePropertyValues,内部也是维护了一个 List<PropertyValue> propertyValueList
集合。MutablePropertyValues 会将属性值转换成 PropertyValue 进行存储。code
(1) 属性htm
private final List<PropertyValue> propertyValueList; // 已经解析过的 PropertyValue private Set<String> processedProperties; private volatile boolean converted = false;
(2) addPropertyValues
能够将 Map、PropertyValue 属性添加到集合中,MutablePropertyValues 统一封装成 PropertyValue 进行存储。
public MutablePropertyValues addPropertyValues(@Nullable Map<?, ?> other) { if (other != null) { other.forEach((attrName, attrValue) -> addPropertyValue( new PropertyValue(attrName.toString(), attrValue))); } return this; } // 全部类型的属性键值对都会转换成 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; } } this.propertyValueList.add(pv); return this; }
注意若是属性值是 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; }
Mergeable 的子类有 ManagedSet、ManagedList、ManagedMap、ManagedProperties、ManagedArray,合并也很简单,以 ManagedList 为例:
public List<E> merge(@Nullable Object parent) { List<E> merged = new ManagedList<>(); merged.addAll((List<E>) parent); merged.addAll(this); return merged; }
(3) getPropertyValue
public PropertyValue getPropertyValue(String propertyName) { for (PropertyValue pv : this.propertyValueList) { if (pv.getName().equals(propertyName)) { return pv; } } return null; }
(4) changesSince
查找相对 old 发生变化的全部元素。
@Override public PropertyValues changesSince(PropertyValues old) { MutablePropertyValues changes = new MutablePropertyValues(); // 1. 返回空集合 if (old == this) { return changes; } // 2. 返回 propertyValueList 中有而 old 没有的元素集合 for (PropertyValue newPv : this.propertyValueList) { PropertyValue pvOld = old.getPropertyValue(newPv.getName()); if (pvOld == null || !pvOld.equals(newPv)) { changes.addPropertyValue(newPv); } } return changes; }
天天用心记录一点点。内容也许不重要,但习惯很重要!