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; }
天天用心記錄一點點。內容也許不重要,但習慣很重要!