「这是我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战」
1. 前言
主要作用:应用给定的属性值,解析此bean工厂中对其他bean的任何运行时引用。必须使用深层复制,所以我们不会永久修改这个属性
org.springframework.context.support.AbstractApplicationContext#refresh --》 org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization --》 org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons --》 org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String) --》 org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean --》 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[]) --》 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean --》 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean --》 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues
2. 源码讲解
老样子,这个方法源码还是比较长,这里我们还是一段一段看
2.1 第一部分
这里的pvs ,实际上在前面讲的 populateBean 方法中的 autowireByName,autowireByType等方法都会把找到的属性和对象放入到pvs的propertyValueList,然后在调用当前方法。
-
这里首先判断,当pvs为null时,则说明没有需要注入给当前bean 的值,直接返回即可。
-
当系统有安全策略管理器的时候,且bw 是 BeanWrapperImpl 的实例,则把工厂的访问控制上下文设为bw的安全上下文。(ps: Spring 默认的 BeanWrapper 实现类就是 BeanWrapperImpl)
- getAccessControlContext : 获取当前工厂的访问控制上下文
- getAccessControlContext : 获取当前工厂的访问控制上下文
-
MutablePropertyValues 是 PropertyValues 的默认实现类,它允许简单的属性操作,并提供构造函数来支持从Map进行深度复制和构造。
-
orginal : 记录原始的属性和列表
2.2 第二部分
-
当 pvs 是 MutablePropertyValues 的实例时,把pvs 强转成 MutablePropertyValues。(通常默认pvs就是 MutablePropertyValues 类型的)
- mpvs.isConverted(): 返回当前 MutablePropertyValues 是否仅包含转换后的值,(如果还有需要转换的值,返回false)
- 如果当前 MutablePropertyValues 仅包含转换后的值,则直接把它赋给 bw ,返回即可。
- 否则的话,把 mpvs 的 propertyValueList 赋给 original
-
否则的话, 直接获取 pvs 的 PropertyValue[]并转成list 赋给 original
-
getCustomTypeConverter : 获取自定义的类型转换器,若是它为null 则把 bw(BeanWrapper 它也实现了 TypeConverter) 赋给 converter
-
BeanDefinitionValueResolver:在bean工厂实现中使用的Helper类,解析bean定义对象中包含的值,转换为应用于目标bean实例的实际值。
2.3 第三部分
看上面的注释也说了,这部分代码的主要作用就是:创建深拷贝,解决值的任何引用
- 首先通过前面 original 的大小,创建一个记录需要深拷贝的属性值的 list
- resolveNecessary : 是否需要解析
- 遍历 original ,当取出的元素 pv 仅包含转换后的值(即不需要转换),则把它加入 deepCopy
- 否则的话,继续向下处理
- 获取属性名 propertyName,获取属性值 originalValue.
- AutowiredPropertyMarker.INSTANCE : 标记 需要 autowired 注入的值的规范实例
- 如果 originalValue == AutowiredPropertyMarker.INSTANCE 即需要 autowired 注入。
- 先通过 属性名propertyName 获取当前bean 的属性描述符,然后获取当前属性的 写方法
- 若没有写方法,直接抛异常;为指定方法创建一个新的 MethodParameter(封装方法参数规范的Helper类),然后 为前面创建的 MethodParameter 参数创建新的描述符 (将依赖项视为“eager”),把它赋给 originalValue
- 调用 resolveValueIfNecessary 解析 originalValue 并赋给 resolvedValue。
- 创建一个 resolvedValue 的副本 convertedValue
- isWritableProperty: 判断指定属性是不是可写的
- PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName) : 检查指定属性是否是索引属性或者嵌套属性
- caonvertible : 可转换标记
- 如果需要转换的话,则调用 转换该属性值,并赋给 convertedValue
- convertForProperty:转换指定目标属性的给定值。
- 判断解析后的 resolvedValue 和 originalValue 是否相等
- 当它们是相等的
- 如果是可转换的,则设置 pv 的转换值
- setConvertedValue :设置此属性值的转换值,在处理类型转换之后。
- 把当前的pv添加到 deepCopy 中去
- 或者 caonvertible = true 可转换的 && originalValue 是 TypedStringValue 实例 && originalValue不是动态的 && (它是集合或数组)。
- 调用 setConvertedValue
- 把当前的pv添加到 deepCopy 中去
- 否则
- 标记是否需要解析 为true
- 通过 pv 和 处理后的值 convertedValue 创建一个新的 PropertyValue 实例,并加到 deepCopy中去
- 获取属性名 propertyName,获取属性值 originalValue.
2.4 第四部分
- 当mpvs 不为null && resolveNecessary == false,则调用 setConverted,将这个mpvs 标记 不在需要运行时解析
- 用处理后的 deepCopy 创建 MutablePropertyValues实例 设置给bw