Spring Property

  • Author: HuiFer
  • 源码阅读仓库: SourceHot-spring

  • 相关类

    • org.springframework.beans.PropertyValues
    • org.springframework.beans.PropertyValue
    • org.springframework.beans.MutablePropertyValues
  • 类图如下

    images

  • 在 Spring IoC 中,非 Web 工程,使用 xml 或者注解进行配置主要使用到的是 PropertyValuesPropertyValueMutablePropertyValues 三个

    其中 PropertyValues 是继承迭代器,具体实现在MutablePropertyValues 他们处理的对象是PropertyValues

    关系就是这样.

  • 开始类的解析了

PropertyValue

  • org.springframework.beans.PropertyValue

  • 类图

    Spring Property - 图2

  • 这个类暂时只关注两个属性

    1. name: 属性名称
    2. value: 属性值

    对应标签<property name="age" value="30"/>

    属性值一一对应填入.

MutablePropertyValues

  • org.springframework.beans.MutablePropertyValues

  • 属性

    1. propertyValueList:属性列表, key:参数名称,value:具体数据
    2. processedProperties: 已经处理的属性名称
    3. converted: 是否转换
  1. public class MutablePropertyValues implements PropertyValues, Serializable {
  2. /**
  3. * 属性列表, key:参数名称,value:具体数据
  4. */
  5. private final List<PropertyValue> propertyValueList;
  6. /**
  7. * 已经处理的属性名称
  8. */
  9. @Nullable
  10. private Set<String> processedProperties;
  11. /**
  12. * 是否转换
  13. */
  14. private volatile boolean converted = false;
  15. }

构造器

  • MutablePropertyValues 的一个构造器. 其他构造器的方式原理实现差不多. 核心是将构造参数转换成PropertyValue对象在放入propertyValueList
  1. public MutablePropertyValues(@Nullable PropertyValues original) {
  2. // We can optimize this because it's all new:
  3. // There is no replacement of existing property values.
  4. if (original != null) {
  5. // 从列表中获取所有可能指
  6. PropertyValue[] pvs = original.getPropertyValues();
  7. this.propertyValueList = new ArrayList<>(pvs.length);
  8. for (PropertyValue pv : pvs) {
  9. // 循环插入 property values
  10. this.propertyValueList.add(new PropertyValue(pv));
  11. }
  12. }
  13. else {
  14. this.propertyValueList = new ArrayList<>(0);
  15. }
  16. }

PropertyValue 的构造方法

  1. public PropertyValue(PropertyValue original) {
  2. Assert.notNull(original, "Original must not be null");
  3. this.name = original.getName();
  4. this.value = original.getValue();
  5. this.optional = original.isOptional();
  6. this.converted = original.converted;
  7. this.convertedValue = original.convertedValue;
  8. this.conversionNecessary = original.conversionNecessary;
  9. this.resolvedTokens = original.resolvedTokens;
  10. setSource(original.getSource());
  11. copyAttributesFrom(original);
  12. }
  • 除了最后一行是一个复杂调用. 前面几行代码都是属性赋值操作.
    • 最后一行代码会调用AttributeAccessor接口上的方法.

AttributeAccessor

  • org.springframework.core.AttributeAccessor

  • 完整的方法列表及作用注释

  1. public interface AttributeAccessor {
  2. /**
  3. * 设置属性值
  4. * @param name 属性值名称
  5. * @param value 属性值
  6. */
  7. void setAttribute(String name, @Nullable Object value);
  8. /**
  9. * 通过属性名称获取属性值
  10. *
  11. * @param name 属性值名称
  12. * @return 属性值
  13. */
  14. @Nullable
  15. Object getAttribute(String name);
  16. /**
  17. * 移除指定属性名称的值,返回移除的属性值
  18. *
  19. * @param name 属性值名称
  20. * @return 移除的属性值
  21. */
  22. @Nullable
  23. Object removeAttribute(String name);
  24. /**
  25. * 是否包含属性名称
  26. * @param 属性名称
  27. */
  28. boolean hasAttribute(String name);
  29. /**
  30. * 属性名称列表
  31. */
  32. String[] attributeNames();
  33. }
  • 回到org.springframework.core.AttributeAccessorSupport#copyAttributesFrom方法
  1. protected void copyAttributesFrom(AttributeAccessor source) {
  2. Assert.notNull(source, "Source must not be null");
  3. // 获取属性名称列表
  4. String[] attributeNames = source.attributeNames();
  5. // 循环属性名称列表
  6. for (String attributeName : attributeNames) {
  7. // 设置属性
  8. // name: 属性名称,value: 从入参中获取属性名称对应的属性值
  9. setAttribute(attributeName, source.getAttribute(attributeName));
  10. }
  11. }

setAttribute

  • 一个 map 操作
  1. @Override
  2. public void setAttribute(String name, @Nullable Object value) {
  3. Assert.notNull(name, "Name must not be null");
  4. if (value != null) {
  5. this.attributes.put(name, value);
  6. }
  7. else {
  8. removeAttribute(name);
  9. }
  10. }

addPropertyValue

  • org.springframework.beans.MutablePropertyValues#addPropertyValue(org.springframework.beans.PropertyValue)
  1. public MutablePropertyValues addPropertyValue(PropertyValue pv) {
  2. // 循环获取 属性对象
  3. for (int i = 0; i < this.propertyValueList.size(); i++) {
  4. // 正在处理的 属性对象
  5. PropertyValue currentPv = this.propertyValueList.get(i);
  6. // 正在处理的属性对象名称和添加的属性对象名称比较
  7. // 如果相同会做一个合并操作
  8. if (currentPv.getName().equals(pv.getName())) {
  9. // 合并属性
  10. pv = mergeIfRequired(pv, currentPv);
  11. // 重新设置
  12. setPropertyValueAt(pv, i);
  13. return this;
  14. }
  15. }
  16. // 放入 list 集合
  17. this.propertyValueList.add(pv);
  18. return this;
  19. }

mergeIfRequired

  • org.springframework.beans.MutablePropertyValues#mergeIfRequired

  • 这段代码会取舍新老数据.

    1. 如果是Mergeable类型会做合并操作
    2. 直接返回新数据
  1. private PropertyValue mergeIfRequired(PropertyValue newPv, PropertyValue currentPv) {
  2. Object value = newPv.getValue();
  3. if (value instanceof Mergeable) {
  4. Mergeable mergeable = (Mergeable) value;
  5. if (mergeable.isMergeEnabled()) {
  6. // 获取合并的结果,放入对象
  7. Object merged = mergeable.merge(currentPv.getValue());
  8. // 创建新的 属性对象
  9. return new PropertyValue(newPv.getName(), merged);
  10. }
  11. }
  12. return newPv;
  13. }
  • 配合测试代码,跟容易看懂.

    1. @Test
    2. public void testAddOrOverride() {
    3. MutablePropertyValues pvs = new MutablePropertyValues();
    4. pvs.addPropertyValue(new PropertyValue("forname", "Tony"));
    5. pvs.addPropertyValue(new PropertyValue("surname", "Blair"));
    6. pvs.addPropertyValue(new PropertyValue("age", "50"));
    7. doTestTony(pvs);
    8. PropertyValue addedPv = new PropertyValue("rod", "Rod");
    9. pvs.addPropertyValue(addedPv);
    10. assertThat(pvs.getPropertyValue("rod").equals(addedPv)).isTrue();
    11. PropertyValue changedPv = new PropertyValue("forname", "Greg");
    12. pvs.addPropertyValue(changedPv);
    13. assertThat(pvs.getPropertyValue("forname").equals(changedPv)).isTrue();
    14. }

Mergeable

新的接口Mergeable

  • org.springframework.beans.Mergeable
  1. public interface Mergeable {
  2. /**
  3. * 是否需要合并
  4. */
  5. boolean isMergeEnabled();
  6. /**
  7. * 合并方法
  8. */
  9. Object merge(@Nullable Object parent);
  10. }

Spring Property - 图3

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