盘点 SpringIOC Bean 创建之属性注入

总文档 :文章目录

Github : github.com/black-ant

一 . 前言

上一篇说了盘点 SpringIOC : Bean 创建主流程 , 这一篇把第二个主要环节 属性注入

还是来看一个很常见的图 , 来源于 @ topjava.cn/article/139…

beanSelf.jpg

1.1 这篇文档的属性注入到底包含了哪些内容 ?

PS :无意中发现这篇文章不能只局限于 populateBean , 所以后续会在这个小章节陆续完善如下信息 , 感兴趣的可以持续关注 !

Bean 的属性处理主要范围为为Bean 进行注入 ,按照我们一般了解的 , Bean 注入主要包括三种注入方式 : 属性 / 构造器 / setter

  • 方式一 : 通过构造器 @Autowired 主流程
  • 方式二 : 通过属性上 @Autowired 主流程
  • 方式三 : 通过 setter 方式 @Autowired 主流程

方式一 : 通过构造器 @Autowired 主流程

1
2
3
4
5
java复制代码@Autowired
public AutowiredService(CommonService commonService, BeanAService beanAService) {
this.commonService = commonService;
this.beanAService = beanAService;
}

image-20210519112021433.png

1
2
3
4
5
6
7
8
9
10
11
12
java复制代码//上图是一张 doCreateBean 方法中 , 执行 createBeanInstance(beanName, mbd, args) 的属性图 
//可以看到 , 在 BeanWrapper 中 , 2个 Autowired 的对象已经处理了

// 这里被触发的主要原因是因为 createBeanInstance 中如下代码 :
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}

// autowireConstructor 核心代码
C- ConstructorResolver
M- autowireConstructor : 处理构造器注入 -> 附录二

方式二 : 通过属性上 @Autowired 主流程

image.png

上图可以看到 , createBeanInstance 后 2个属性均未开始加载 , 但是我们又知道 , 属性的注入是在 initializeBean前完成 , 以保证初始化方法可用.

1
2
3
4
5
6
7
8
9
java复制代码// 在处理 populateBean 时 , 会对 InstantiationAwareBeanPostProcessor 进行处理 , 其中主要有这些

org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor
org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
// .....

最终的核心就是 AutowiredAnnotationBeanPostProcessor , 这个我们在 populateBean 后面细讲

方式三 : setter

1
java复制代码//方式三和方式二类型 , 处理的 PostProcessor 主要为 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor

二 . 属性注入流程

区别于上面的 autowired , populateBean 还主要处理了什么?

为了更好的理解流程 , 这里要区分一下 , 除了 autowired 注入属性外 , populateBean 中还有一个重要的概念叫 PropertyValues

1
2
3
java复制代码TODO : 这一块有大问题 , 其来源始终没有弄懂,  查阅资料大多数也是一笔带过 
// 这里先埋坑 , 晚上再详细的看看 , 猜测是由于老式 xml 方式构建对象时 , 有个 property 属性
// 如果有清楚的 , 麻烦提点一下 ,非常感谢

我们来好好的看一下 属性注入的流程

2.1 属性注入的入口

1
2
3
java复制代码C- AbstractAutowireCapableBeanFactory 
M173_05- doCreateBean(beanName, mbdToUse, args) : 创建 Bean 对象
- populateBean : 属性注入操作 -> M173_30

2.2 属性注入主流程

属性的注入主流程是在 doCreateBean 中 , 回忆循环依赖的相关概念 ,在调用populateBean 之前 , 已经产生了一个对象 , 该对象未完成相关的属性注入

先来看一下传入的属性

populateBean(beanName, mbd, instanceWrapper);

image.png

image.png

PS:属性注入是在 InitializingBean 之前 , 所以相关的初始化方法可以使用 @Autowired 对象 , 这个后续详细说说

属性注入 populateBean 逻辑

逻辑整体上分为7步 :

  • Step 1 : BeanWrapper 空实例的处理 : 实例化之前要对空实例进行判断和处理
  • Step 2 : BeanPostProcessors 处理
  • Step 3 : 为 bean 注入属性
  • Step 4 : 判断是否注册了 InstantiationAwareBeanPostProcessors 以及是否需要依赖检查
  • Step 5 : BeanPostProcessor 处理 , 此处主要是 InstantiationAwareBeanPostProcessor 的处理
  • Step 6 : 依赖检查
  • Step 7 : applyPropertyValues(beanName, mbd, bw, pvs)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
java复制代码
C173- AbstractAutowireCapableBeanFactory
M173_30- populateBean(String beanName, RootBeanDefinition mbd,BeanWrapper bw)
P- String beanName
P- RootBeanDefinition mbd
P- @Nullable BeanWrapper bw
1- BeanWrapper 空实例的处理 : 实例化之前要对空实例进行判断和处理
- 如果 BeanWrapper 为空 , 且mbd有值 ,无法对空实例初始化 , 抛出 BeanCreationException
- 如果 BeanWrapper 为空 , 且mbd无属性 , 直接返回
2- BeanPostProcessors 处理
?- 这里是PostProcesssors 最后一次加载机会 , 该方法为bean中定义bean 初始化时默认做的操作
IF- bean 不是合成的 , bean 持有 InstantiationAwareBeanPostProcessor ->
FOR- 迭代所有的 BeanPostProcessors : getBeanPostProcessors
- InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
?- 当返回值为 false 的情况下会停止整个bean 的属性注入 , 直接return , 跳过属性注入操作
3- 为 bean 注入属性
- new MutablePropertyValues(pvs) -- 获取bean 的属性值
- PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null) -- pvs 来源
- 判断是否有自动注入的注解 -> 自动注入属性
- 将 PropertyValues 封装成 MutablePropertyValues 对象 , 该对象允许对属性进行简单操作 -> PS:M173_30_3
- 通过 mbd.getResolvedAutowireMode() 区别是名称注入还是类型注入 -> 同步不同的类型注入 -> PS:M173_30_4
- AUTOWIRE_BY_NAME -- autowireByName(beanName, mbd, bw, newPvs);
- AUTOWIRE_BY_TYPE -- autowireByType(beanName, mbd, bw, newPvs);
4- 判断是否注册了 InstantiationAwareBeanPostProcessors 以及是否需要依赖检查 (needsDepCheck)
- 是否注册 : hasInstantiationAwareBeanPostProcessors()
- 是否依赖检查 : mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE
5- 当步骤4 告知需要 BeanPostProcessor 处理 , 即 hasInstAwareBpps + BeanPostProcessor 不为空
- pvs 为 null 会 通过 mbd.getPropertyValues(); 获取一个
- 遍历 BeanPostProcessor 数组 ,instanceof InstantiationAwareBeanPostProcessor, 对Bean 进行前置处理
- PropertyValues = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); --- 获取 PropertyValues
- 如果 PropertyValues 为null , 则通过 ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); 完成构建
- filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
6- 依赖检查
- filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
- checkDependencies(beanName, mbd, filteredPds, pvs); -- 依赖检查,对应 depends-on 属性
7- applyPropertyValues(beanName, mbd, bw, pvs); --- 将属性应用到 bean 中


C175- AbstractBeanDefinition : MutablePropertyValues 类的作用
M175_01- getResolvedAutowireMode : 获得 Autowired 的类型

PS:M173_30_3 MutablePropertyValues 的作用

允许简单的属性操作,并提供构造函数来支持从Map深度复制和构造

1
2
3
java复制代码C190- MutablePropertyValues
F190_01- List<PropertyValue> propertyValueList
F190_02- Set<String> processedProperties

PS:M173_30_4 通过不同类型注入

1
2
3
4
5
6
7
8
9
10
11
12
13
java复制代码C173- AbstractAutowireCapableBeanFactory
M173_10- autowireByName : 根据属性名称,完成自动依赖注入
- 获取Bean 对象中非简单属性 (非基本类型的对象)
FOR- 循环该该属性数组 , 递归通过name获取相关的bean
- 将相关的bean 加入 MutablePropertyValues
- 属性依赖注入 -- registerDependentBean(propertyName, beanName);
- Map<String, Set<String>> dependentBeanMap : beanName - > 依赖 beanName 的集合
- Map<String, Set<String>> dependenciesForBeanMap : 依赖 beanName - > beanName 的集合
- 1 获取 beanName
- 2 添加 <canonicalName, <dependentBeanName>> 到 dependentBeanMap 中
- 3 添加 <dependentBeanName, <canonicalName>> 到 dependenciesForBeanMap 中
M173_11- autowireByType : 根据属性类型,完成自动依赖注入
- 整体方法类似于byName , 逻辑上是找到需要依赖注入的属性,然后通过迭代的方式寻找所匹配的 bean

M173_10 autowireByName 源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
java复制代码protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
// 判断 Bean 是否加载了
if (containsBean(propertyName)) {
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
// 为给定bean注册一个依赖bean,以便在销毁给定bean之前销毁它
registerDependentBean(propertyName, beanName);
//... log
}
else {
//... log
}
}
}

// Pro 1 : containsBean 详情
- containsSingleton : 单例模式的缓存 , 详情可以看循环依赖篇
- containsBeanDefinition : beanDefinitionMap.containsKey(beanName) , registerBeanDefinition 时添加
- parentBeanFactory.containsBean : 从 Parent 中获取

// Pro 2 : registerDependentBean 逻辑 ,其中干了这样几件事
public void registerDependentBean(String beanName, String dependentBeanName) {
// 确定原始名称,将别名解析为规范名称 , 这里实际上就是对 aliasMap 循环
String canonicalName = canonicalName(beanName);

// 对 dependentBeanMap 上锁 , 保证多线程唯一
// dependentBeanMap : 谁依赖我 ,bean名称到依赖bean名称的集合
synchronized (this.dependentBeanMap) {
Set<String> dependentBeans =this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}

// dependenciesForBeanMap : 我依赖谁 , bean名称到bean依赖项的bean名称的集合
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}

// PS : 关于 dependentBeanMap 和 dependenciesForBeanMap 可以看看这篇文档 :
https://blog.csdn.net/xieyinghao_bupt/article/details/109552054

image.png

M173_11 autowireByType 源码

ps : 这里一开始案例太少 ,没看懂 , 回头翻了一下 死磕系列的笔记 , 终于搞清楚了

这一段参照死磕 IOC , 仅补充部分逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
java复制代码protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 定义类型转换方法的接口
// 使用自定义的 TypeConverter,用于取代默认的 PropertyEditor 机制
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
// 通常上面的那个接口都为null , 这里就会直接使用 BeanWrapper
converter = bw;
}

Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
// 获取非简单属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
// 遍历 propertyName 数组
for (String propertyName : propertyNames) {
try {
// 获取 PropertyDescriptor 实例
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
if (Object.class != pd.getPropertyType()) {
// 探测指定属性的 set 方法
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
// 解析指定 beanName 的属性所匹配的值,并把解析到的属性名称存储在 autowiredBeanNames 中
// 当属性存在过个封装 bean 时将会找到所有匹配的 bean 并将其注入
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
// 遍历 autowiredBeanName 数组
for (String autowiredBeanName : autowiredBeanNames) {
// 属性依赖注入
registerDependentBean(autowiredBeanName, beanName);
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}


PS: autowireByType 可以通过 @Bean(initMethod = "initMethod", autowire = Autowire.BY_TYPE) 进行触发

// Pro 1 : PropertyDescriptor 对象
作用 : PropertyDescriptor描述了Java bean通过一对访问器方法导出的一个属性
方法 : getPropertyDescriptor : 获取包装对象的特定属性的属性描述符


// Pro 2 : BeanUtils.getWriteMethodParameter(pd)
- Method writeMethod = pd.getWriteMethod() : 获取应用于写入属性值的方法
- 这里应该就是 构造器和 Setter 等逻辑 -> PS:M173_11_01
- new MethodParameter(writeMethod, 0)


// Pro 3 : DependencyDescriptor
描述符,用于即将注入的特定依赖项。包装构造函数参数、方法参数或字段,允许对它们的元数据进行统一访问。

PS:M173_11_01 可以看到这里是 setter 方法
image.png

关于默认注入类型的问题

之前看资料的时候 , 一直都是说 AutoWired 默认使用 byType , 但是实际debug 中 ,发现并没有 , 在属性注入的时候 , 返回的类型为 0 , 即AUTOWIRE_NO , 其实这个是要分情况处理的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
java复制代码
public int getResolvedAutowireMode() {
if (this.autowireMode == AUTOWIRE_AUTODETECT) {
// Work out whether to apply setter autowiring or constructor autowiring.
// If it has a no-arg constructor it's deemed to be setter autowiring,
// otherwise we'll try constructor autowiring.
Constructor<?>[] constructors = getBeanClass().getConstructors();
for (Constructor<?> constructor : constructors) {
if (constructor.getParameterCount() == 0) {
return AUTOWIRE_BY_TYPE;
}
}
return AUTOWIRE_CONSTRUCTOR;
}
else {
return this.autowireMode;
}
}

resolveDependency 详情

resolveDependency 方法主要被 autowireByType 调用 , 此外在 AutowiredAnnotationBeanPostProcessor 中也有所涉及

作用 : 针对此工厂中定义的bean解析指定的依赖项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
java复制代码public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}

PS:M173_30_5 InstantiationAwareBeanPostProcessor 结构

结构 : BeanPostProcessor的子接口

功能 : 添加了一个实例化之前的回调函数和一个实例化之后但在显式属性设置或自动装配发生之前的回调函数

常用 : 创建带有特殊target Source的代理(池化目标、延迟初始化目标等) , 实现额外的注入策略

特点 : 这个接口中 , 除了BeanPostProcessor默认的 postProcessBeforeInstantiation , postProcessAfterInstantiation 的方法外 , 还有一个额外的方法 postProcessProperties , postProcessPropertyValues

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
java复制代码// public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor
// 此处通过 hasInstantiationAwareBeanPostProcessors 判断是否继承相关的对象


// ===========================================
// Pro 1 : 配置的起点
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
// PS : hasInstantiationAwareBeanPostProcessors 归属于父类 AbstractBeanFactory
private volatile boolean hasInstantiationAwareBeanPostProcessors;
//.........
}


// ===========================================
// Pro 2 : 属性的设置
// 可以看到 , 这里通过 addBeanPostProcessor 中配置开关
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
this.beanPostProcessors.remove(beanPostProcessor);
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
this.beanPostProcessors.add(beanPostProcessor);
}

// ===========================================
// Pro 3 : 看一下 InstantiationAwareBeanPostProcessor 的调用时
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

// Step 3 : BeanPostProcessors 处理 , 主要是 postProcessAfterInstantiation 前置处理
// PS : 这里只有继承了 InstantiationAwareBeanPostProcessor 的类才能进行 postProcessAfterInstantiation
// ..................
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}

// ...................
// Step 5 : BeanPostProcessor 处理 , 此处主要是 InstantiationAwareBeanPostProcessor 的处理
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 实现InstantiationAwareBeanPostProcessor 特有的 postProcessProperties
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
// 实现InstantiationAwareBeanPostProcessor 特有的 postProcessPropertyValues
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}


// ===========================================
// Pro 4 : postProcessProperties 和 postProcessPropertyValues 的作用

postProcessProperties :
- 在工厂将给定的属性值应用到给定bean之前对它们进行后处理,不需要任何属性描述符.

postProcessPropertyValues :
- 在工厂将给定的属性值应用到给定bean之前对它们进行后处理。
- 允许替换要应用的属性值,通常是通过基于原始的PropertyValues创建一个新的MutablePropertyValues实例,添加或删除特定的值

InstantiationAwareBeanPostProcessor.png

2.3 PropertyValue 和 applyPropertyValues 的作用

整个流程中 , 反复出现了一个属性 PropertyValue , 我们来看一下其中的前世今生

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
java复制代码// M173_11 源代码
// TODO
C173- AbstractAutowireCapableBeanFactory
M173_15- applyPropertyValues : 属性的注入操作
?- 之前的操作只是完成了所有注入属性的获取,将获取的属性封装在 PropertyValues 的实例对象 pvs 中
?- 此处将属性应用到已经实例化的 bean 中
1- BeanWrapperImpl.setSecurityContext
?- 设置 BeanWrapperImpl 的 SecurityContext 属性
2- 准备属性
- MutablePropertyValues mpvs
- List<PropertyValue> original
3- 获取属性集合
- original = mpvs.getPropertyValueList() : mpvs 就是 pvs , 只不过转换过
/ original = Arrays.asList(pvs.getPropertyValues())
// 此处有个中间节点 : 如果已经设置完成 , 则直接完成配置 , 并且 return
4- 准备属性
- TypeConverter converter = getCustomTypeConverter()
- new BeanDefinitionValueResolver(this, beanName, mbd, converter) : 用于解析未被解析的对象
- List<PropertyValue> deepCopy = new ArrayList<>(original.size())
5- For 循环 List<PropertyValue> original , 对 PropertyValue 进行转换
?- 属性是不能直接设置进去的 , 需要通过处理再设置
- 判断属性值是否转换 , 非 MutablePropertyValues 类型会直接使用原始类型
- 否则先获取 propertyName , originalValue
// 注意 , 此处进行了 Autowired 处理
- 如果是 Autowired 类型
- Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod()
?- 如果是 Autowired 属性 , 获取包装对象的特定属性的属性描述符后再获取应用于写入属性值的方法
- new DependencyDescriptor(new MethodParameter(writeMethod, 0), true)
?- 为方法或构造函数参数创建新的描述符
// 注意 , 这里开始进行属性转换 , 分为2步
5.1- convertedValue = valueResolver.resolveValueIfNecessary
?- 给定PropertyValue,返回一个值,在必要时解析对工厂中其他bean的任何引用
5.2- convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter)
?- 如果可写 , 且不是给定的属性路径是否指示索引或嵌套属性
- setConvertedValue + 添加到 4步 List<PropertyValue> deepCopy 集合中
6- 注入核心 : 为属性设置属性值 --  bw.setPropertyValues(mpvs);

M173_15 applyPropertyValues 源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
java复制代码protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs.isEmpty()) {
return;
}
// Step 1 : 设置 BeanWrapperImpl 的 SecurityContext 属性
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}

// Step 2 : 属性准备
MutablePropertyValues mpvs = null;
List<PropertyValue> original;

// Step 3 : 获取属性集合
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
// 已转换直接返回
if (mpvs.isConverted()) {
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
original = Arrays.asList(pvs.getPropertyValues());
}

// Step 4 : 属性准备
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
// Step 5 :属性循环转换
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
if (originalValue == AutowiredPropertyMarker.INSTANCE) {
Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {
throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
}
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
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));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}

// Step 6 : 注入核心
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}

总结

看起来挺长的 , 但是回头看了死磕系列感觉还有很多地方自己还没有看懂 , 后面有时间把这个坑填上

太晚了 , 比不过卷王们 ,洗洗睡了

附录

附录一 : M173_30 populateBean 核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
java复制代码protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// BeanWrapper 空实例的处理 : 实例化之前要对空实例进行判断和处理
if (bw == null) {
// 如果 BeanWrapper 为空 , 且mbd有值 ,无法对空实例初始化 , 抛出 BeanCreationException
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// 如果 BeanWrapper 为空 , 且mbd无属性 , 直接返回
return;
}
}

// isSynthetic : 返回此bean定义是否是“合成的”,即不是由应用程序本身定义的
// hasInstantiationAwareBeanPostProcessors : bean 持有 InstantiationAwareBeanPostProcessor
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 循环所有的
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 此处只会处理 InstantiationAwareBeanPostProcessor
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}

// 获取bean 的属性值
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

int resolvedAutowireMode = mbd.getResolvedAutowireMode();
// 判断是否有自动注入的注解 -> 自动注入属性
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
// 将 PropertyValues 封装成 MutablePropertyValues 对象 , 该对象允许对属性进行简单操作 -> PS:M173_30_3
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 通过 mbd.getResolvedAutowireMode() 区别是名称注入还是类型注入 -> 同步不同的类型注入 -> PS:M173_30_4
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}

if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}

// 判断是否注册了 InstantiationAwareBeanPostProcessors 以及是否需要依赖检查 (needsDepCheck)
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
//
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
// 依赖检查,对应 depends-on 属性
checkDependencies(beanName, mbd, filteredPds, pvs);
}

if (pvs != null) {
// 将属性应用到 bean 中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}

附录二 : autowireConstructor 主方法 TODO

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
java复制代码public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {

BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);

Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;

if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}

if (constructorToUse == null || argsToUse == null) {
// Take specified constructors, if any.
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
throw new BeanCreationException(...);
}
}

if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Constructor<?> uniqueCandidate = candidates[0];
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}

// Need to resolve the constructor.
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;

int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}

AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;

for (Constructor<?> candidate : candidates) {

int parameterCount = candidate.getParameterCount();

if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
if (parameterCount < minNrOfArgs) {
continue;
}

ArgumentsHolder argsHolder;
Class<?>[] paramTypes = candidate.getParameterTypes();
if (resolvedValues != null) {
try {
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
if (paramNames == null) {
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
}
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
else {
// Explicit arguments given -> arguments length must match exactly.
if (parameterCount != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}

int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}

if (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(...);
}
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(...);
}

if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}

Assert.state(argsToUse != null, "Unresolved constructor arguments");
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}

附录三 : @Value 的注入时机

1
2
java复制代码
TODO

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%