Spring源码:PropertyValues类及属性注入一

概要

Spring获取Bean的实例时,需要把配置的属性值解析到PropertyValues,然后填充入BeanWrapper中

相关类

  • **MutablePropertyValues类:**PropertyValues接口的默认实现

    public class MutablePropertyValues implements PropertyValues, Serializable {
    
    private final List<PropertyValue> propertyValueList;
    
    private Set<String> processedProperties;
    
    private volatile boolean converted = false;
      //......
    }
  • PropertyValues接口:包含一个或多个PropertyValue对象的容器,通常包含特定目标bean的一个更新。

    public interface PropertyValues {
    
      PropertyValue[] getPropertyValues();
    
      PropertyValue getPropertyValue(String propertyName);
    
      PropertyValues changesSince(PropertyValues old);
    
      boolean contains(String propertyName);
    
      boolean isEmpty();
    }
  • PropertyValue类:保存单个bean属性的信息和值的对象

    public class PropertyValue extends BeanMetadataAttributeAccessor implements Serializable {
    
    private final String name;
    
    private final Object value;
    
    private boolean optional = false;
    
    private boolean converted = false;
    
    private Object convertedValue;
    
    /** Package-visible field that indicates whether conversion is necessary */
    volatile Boolean conversionNecessary;
    
    /** Package-visible field for caching the resolved property path tokens */
    transient volatile Object resolvedTokens;
    }
  • **BeanMetadataAttributeAccessor类:**AttributeAccessorSupport的扩展类

    public class BeanMetadataAttributeAccessor extends AttributeAccessorSupport implements BeanMetadataElement {
    
    private Object source;
      //......
    }
  • **AttributeAccessorSupport抽象类:**AttributeAccessor的基本实现类

    public abstract class AttributeAccessorSupport implements AttributeAccessor, Serializable {
    
    private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(0);
      //......
    }
  • AttributeAccessor接口

    public interface AttributeAccessor {
    void setAttribute(String name, Object value);
    
    Object getAttribute(String name);
    
    Object removeAttribute(String name);
    
    boolean hasAttribute(String name);
    
    String[] attributeNames();
    }

属性注入

Spring获取Bean的实例时,需要把配置的属性值解析到PropertyValues,然后填充入BeanWrapper中,注入函数在抽象类AbstractAutowireCapableBeanFactory中的applyPropertyValues方法中,详细分析如下:

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
    // 若没有要注入的属性,直接返回
    if (pvs == null || pvs.isEmpty()) {
        return;
    }

    MutablePropertyValues mpvs = null;
    // 需要转换的属性
    List<PropertyValue> original;

    if (System.getSecurityManager() != null) {
        if (bw instanceof BeanWrapperImpl) {
            ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
        }
    }


    if (pvs instanceof MutablePropertyValues) {
        mpvs = (MutablePropertyValues) pvs;
        if (mpvs.isConverted()) {
            // 若该mpvs中的所有属性值都已经转换为对应的类型,则把mpvs设置到BeanWrapper中,返回
            bw.setPropertyValues(mpvs);
            return;
        }
        original = mpvs.getPropertyValueList();
    } else {
        original = Arrays.asList(pvs.getPropertyValues());
    }

    // 获取用户自定义类型转换器
    TypeConverter converter = getCustomTypeConverter();
    if (converter == null) {
        converter = bw;
    }
    //获取BeanDefinitionValueResolver,该Bean用于将bean定义对象中包含的值解析为应用于目标bean实例的实际值。
    BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
    // 用于存放实际解析后的属性集合
    List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
    boolean resolveNecessary = false;
    // 遍历未解析的属性
    for (PropertyValue pv : original) {
        if (pv.isConverted()) {
            // 若该属性已经解析过
            deepCopy.add(pv);
        } else {
            // 若该属性没有被解析过
            String propertyName = pv.getName(); // 属性名称
            Object originalValue = pv.getValue(); // 属性未经类型转换的值
            // 解析值
            Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
            Object convertedValue = resolvedValue;
            // 属性可写 && 不是嵌套(如foo.bar,java中用getFoo().getBar()表示)或者索引(如person.addresses[0])属性
            boolean convertible = bw.isWritableProperty(propertyName) &&
                        !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
            if (convertible) {
                // 用类型转换器进行转换
                convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
            }

           // 可能将转换后的值存储在merged bean definition中,避免对每个创建的bean实例进行重新转换。
            if (resolvedValue == originalValue) {
                if (convertible) {
                    pv.setConvertedValue(convertedValue);
                }
                deepCopy.add(pv);
            } else if (convertible && originalValue instanceof TypedStringValue && !((TypedStringValue) originalValue).isDynamic() && !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
                pv.setConvertedValue(convertedValue);
                deepCopy.add(pv);
            } else {
                resolveNecessary = true;
                deepCopy.add(new PropertyValue(pv, convertedValue));
            }
        }
    } // for

    if (mpvs != null && !resolveNecessary) {
        // 标记mpvs已经转换
        mpvs.setConverted();
    }
    // 构造MutablePropertyValues并填充到BeanWrapper中
    bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bboyzqh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值