从源码角度理解Spring Bean 的属性填充

从源码角度理解Spring Bean 的属性填充

一、引言

​ 在Spring框架中,一个Bean的完整生命周期涉及多个复杂阶段。其中,属性填充(Property Population)是连接实例化初始化的关键桥梁。

​ 为了让你更清晰地理解上下文,我们先回顾一下AbstractAutowireCapableBeanFactory#doCreateBean方法的核心逻辑。这是所有非懒加载单例Bean创建的必经之路:

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
// AbstractAutowireCapableBeanFactory.java
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) {
BeanWrapper instanceWrapper = null;
// 1. 实例化阶段:通过构造器或工厂方法创建Bean实例
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();

// 2. 提前暴露早期引用(解决循环依赖的关键)
// 提前曝光对象,但此时属性还未填充
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

Object exposedObject = bean;
try {
// 3. ★★★ 核心主题:属性填充(依赖注入发生的地方)★★★
populateBean(beanName, mbd, instanceWrapper);

// 4. 初始化阶段:执行Aware接口、BeanPostProcessor前置处理、init方法、BeanPostProcessor后置处理
exposedObject = initializeBean(beanName, exposedObject, mbd);
} catch (Throwable ex) {
// ... 异常处理
}

// ... 处理循环依赖的最终校验
return exposedObject;
}

​ 从这段代码可以看出,populateBean方法夹在“实例化”与“初始化”之间。这意味着当进入populateBean时,对象已经存在(通过反射调用了构造器),但对象内部的成员变量(如@Autowired@Resource<property>标签等标注的字段)还是空的。我们的任务就是把这些配置或注解中定义的值,准确地塞进这些空字段里。

2. 属性填充入口:populateBean 宏观俯瞰

populateBean是整个属性注入流程的总调度室。它的逻辑虽然复杂,但结构非常清晰,采用了多个前置处理 + 单一执行的模式。

我们直接切入AbstractAutowireCapableBeanFactory中的源码

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
// AbstractAutowireCapableBeanFactory.java
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
// 1. 获取Bean定义中的属性值(通常来源于XML配置中的<property>)
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

// 如果包装类为空,但有属性需要设置,则抛出异常
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(...);
}
else {
return; // 对象为null且无属性可设置,直接返回
}
}

// 2. 【扩展点1】 实例化后、属性填充前的终极控制
// 给InstantiationAwareBeanPostProcessors一个机会,决定是否需要Spring继续填充属性
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
// 如果postProcessAfterInstantiation返回false,表示Bean自己处理了属性注入,Spring将不再进行后续的填充
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}

// 如果上述处理器阻止了默认的属性填充,直接返回
if (!continueWithPropertyPopulation) {
return;
}

// 3. 处理按名称(byName)或按类型(byType)的自动装配
// 这部分主要处理在BeanDefinition中显式设置的autowire模式
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {

MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

// 按名称自动装配
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}

// 按类型自动装配
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}

pvs = newPvs; // 更新属性值列表
}

// 4. 【扩展点2】 对已解析的属性进行后置处理
// 这是注解驱动注入(如@Autowired、@Resource)发生的地方
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
// AutowiredAnnotationBeanPostProcessor会在此处调用,直接通过反射设置属性值
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
// 兼容旧版本(已废弃)的postProcessPropertyValues方法
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}

// 5. 依赖检查(主要用于旧版本,现代Spring开发中较少使用)
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}

// 6. ★★★ 最终执行者:将收集到的所有属性值应用到Bean对象上 ★★★
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}

2.1 宏观流程小结

  1. 前置拦截:通过postProcessAfterInstantiation可以完全关闭自动属性填充。
  2. 自动装配:处理byNamebyType的原始Spring自动装配(基于setter)。
  3. 注解后置处理:这是最关键的步骤,处理@Autowired等注解,将依赖对象注入。
  4. 应用属性:将解析后的PropertyValues(包含转换后的值或引用)通过反射/设置器写入对象。

接下来,我们将逐一深入这些核心环节。

3. postProcessAfterInstantiation 扩展点

在正式开始填充属性之前,Spring给了开发者一个“一票否决权”。

1
2
3
4
5
6
7
8
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}

逻辑解析

  • 触发时机:Bean对象已经被实例化出来,但还没设置任何属性。
  • 接口作用InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation返回boolean值。
    • 返回true(默认):Spring继续执行后续的属性填充。
    • 返回false:Spring认为该Bean的依赖注入已经被自定义逻辑处理完毕,将跳过整个populateBean的后续所有步骤(包括byNamebyType、注解注入等)。

设计意图:这个扩展点非常强大,它允许开发者实现完全自定义的属性注入逻辑,或者在某些特殊条件下完全阻止Spring的自动注入。比如,你可以基于外部配置或动态代理来决定是否注入某些属性。

4. 传统自动装配:byName 与 byType 深度解析

​ 在Spring Boot盛行的今天,@Autowired注解已经成为了依赖注入的主流,但理解byNamebyType这两种传统的基于XML的自动装配模式,对于理解Spring的IoC思想演变仍然至关重要。

​ 这段逻辑只有在RootBeanDefinition中明确设置了autowire属性为byNamebyType时才会触发。

4.1 autowireByName:简单直接的名称匹配

autowireByName的逻辑非常直观:找出Bean中所有需要自动装配的属性(非简单类型且未被显式配置),然后拿着这个属性名去容器中找同名的Bean。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// AbstractAutowireCapableBeanFactory.java
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

// 找出所有需要按名称自动装配的属性
// 条件:非简单类型属性,且该属性在pvs中尚未存在(即未被显式赋值)
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
// 关键:容器中是否包含这个名称的Bean?
if (containsBean(propertyName)) {
// 获取依赖Bean实例(这可能触发依赖Bean的创建)
Object bean = getBean(propertyName);
// 将解析出的Bean添加到属性值列表中
pvs.add(propertyName, bean);
// 注册依赖关系(用于销毁时的顺序控制)
registerDependentBean(propertyName, beanName);
}
}
}

什么是“非简单属性”? Spring定义了一套“简单类型”列表,主要包括:StringNumber及其子类、BooleanDateURIURLLocaleClass以及以上类型的数组。如果属性类型不属于这些简单类型,且没有被显式赋值,就会被视为“需要自动装配的非简单属性”

4.2 autowireByType:复杂精妙的类型匹配

相较于byNamebyType要复杂得多,因为它需要处理类型匹配、泛型、以及潜在的多个候选Bean的歧义问题。

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
// AbstractAutowireCapableBeanFactory.java
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw; // BeanWrapper本身也是一个类型转换器
}

Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// 不对Object类型进行自动装配
if (Object.class != pd.getPropertyType()) {
// 获取setter方法的参数(用于解析泛型等信息)
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);

// 定义依赖描述符,指定是否需要多个、是否必须等
DependencyDescriptor desc = new DependencyDescriptor(methodParam, false);

// 关键:通过BeanFactory的依赖解析器解析出匹配的Bean实例
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);

if (autowiredArgument != null) {
// 将解析出的Bean添加到属性值列表中
pvs.add(propertyName, autowiredArgument);
}
// 注册依赖关系
for (String autowiredBeanName : autowiredBeanNames) {
registerDependentBean(autowiredBeanName, beanName);
}
autowiredBeanNames.clear();
}
} catch (BeansException ex) {
throw new UnsatisfiedDependencyException(...);
}
}
}

核心逻辑resolveDependency 方法封装了整个依赖解析的核心算法,它内部会处理:

  1. 类型匹配:找到所有与属性类型匹配的Bean。
  2. 候选筛选:如果有多个Bean匹配,会根据@Primary@PrioritybeanName与属性名的匹配度(byType退化为byName的特性)进行筛选。
  3. 依赖注入:最终确定唯一的候选者并返回其实例。

5. 注解驱动注入:AutowiredAnnotationBeanPostProcessor 的工作机制

如果说byNamebyType是Spring 1.x时代的产物,那么@Autowired@Value@Inject则是现代Spring(2.5+)的事实标准。这些注解的处理并非在populateBean中硬编码,而是通过我们之前提到的扩展点2——InstantiationAwareBeanPostProcessor#postProcessProperties来实现的。

具体的实现类是AutowiredAnnotationBeanPostProcessor

5.1 元数据解析:寻找注入点

在Bean实例化之前(更准确地说是doCreateBean中的applyMergedBeanDefinitionPostProcessors阶段),AutowiredAnnotationBeanPostProcessor会作为一个MergedBeanDefinitionPostProcessor,提前解析出Bean中所有带有@Autowired@Value等注解的字段和方法,并将其封装成InjectionMetadata对象缓存起来。这样做是为了避免在每次注入时都重复进行昂贵的反射解析

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
// AutowiredAnnotationBeanPostProcessor.java
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 查找并缓存注入点
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}

private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;

do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

// 遍历所有字段,查找带有@Autowired等注解的字段
ReflectionUtils.doWithLocalFields(targetClass, field -> {
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
return; // 静态字段不注入
}
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});

// 遍历所有方法,查找带有@Autowired等注解的方法(通常是setter)
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
// ... 类似逻辑
});

elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);

return new InjectionMetadata(clazz, elements);
}

5.2 运行时注入:从缓存到实例

​ 当执行到populateBean中的postProcessProperties时,AutowiredAnnotationBeanPostProcessor直接利用之前缓存的InjectionMetadata信息进行注入。

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
// AutowiredAnnotationBeanPostProcessor.java
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 从缓存中获取该Bean的注入点元数据
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 执行注入
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}

// InjectionMetadata.java
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
// 逐个字段/方法进行注入
element.inject(target, beanName, pvs);
}
}
}

关键点metadata.inject内部会针对每个AutowiredFieldElementAutowiredMethodElement,调用resolveDependency解析出依赖值,然后通过ReflectionUtils.makeAccessibleField.set暴力设置值,或者通过Method.invoke调用setter方法

6. 最后一击:applyPropertyValues 与类型转换

​ 经历了上述阶段,所有需要注入的属性值(包括来自XML的pvsbyName/byType解析出的值、@Autowired直接注入的值)都汇集到了PropertyValues pvs这个对象中。但此时,这些值还“游离”于Bean对象之外。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
// AbstractAutowireCapableBeanFactory.java
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs.isEmpty()) {
return;
}

MutablePropertyValues mpvs = null;
List<PropertyValue> original;

if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
// 如果已经转换过,直接应用并返回(针对已经过类型转换的场景)
if (mpvs.isConverted()) {
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(...);
}
}
original = mpvs.getPropertyValueList();
} else {
original = Arrays.asList(pvs.getPropertyValues());
}

// 获取类型转换器
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw; // BeanWrapper本身实现了TypeConverter
}

// 创建一个用于解析Bean引用的解析器
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
String propertyName = pv.getName();
Object originalValue = pv.getValue();

// ★★★ 核心:解析属性值 ★★★
// 如果originalValue是一个Bean引用(RuntimeBeanReference),或者是类型转换器(TypeConverter),或者是集合等等,
// 都需要在这里进行解析。
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);

// 转换后的值可能与原值不同
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
// ★★★ 核心:类型转换 ★★★
// 将解析后的值转换为目标属性所需的类型
convertedValue = convertIfNecessary(propertyName, propertyValue, resolvedValue, bw, converter);
}

// 记录转换后的值
if (resolvedValue != originalValue || convertedValue != resolvedValue) {
resolveNecessary = true;
pv = new PropertyValue(pv, convertedValue);
}
deepCopy.add(pv);
}

// 将转换后的属性列表设置到MutablePropertyValues并标记为已转换
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
} else {
// 最后,通过BeanWrapper的setPropertyValues方法批量设置属性
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
}

6.1 BeanDefinitionValueResolver:值解析器

resolveValueIfNecessary方法负责处理各种特殊的“值”类型:

  • RuntimeBeanReference:如果值是<ref bean="xxx">,它会调用getBean("xxx")来获取实际的Bean实例。
  • RuntimeBeanNameReference:解析为Bean的名称字符串。
  • ObjectFactory:创建ObjectFactory对象。
  • ManagedArray/List/Set/Map:解析集合中的每个元素(元素可能又是RuntimeBeanReference)。
  • TypedStringValue:将字符串包装类中的字符串值提取出来,准备进行类型转换。

6.2 类型转换:TypeConverter 的魔力

Spring配置文件(XML或Properties)中的值本质上都是字符串。但Java对象的属性可能是DateIntegerBoolean甚至自定义对象。
convertIfNecessary方法利用Spring的类型转换体系(TypeConverter + PropertyEditor + ConversionService)将这些字符串转换成目标类型。
例如,<property name="age" value="20"/>会被从String转换为int

7. 循环依赖的“救命稻草”:三级缓存与提前曝光

理解属性填充,就绕不开循环依赖。Spring解决setter注入的单例Bean循环依赖,正是在属性填充阶段实现的。

回顾doCreateBean开头的代码:

1
2
3
4
5
6
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 在属性填充前,就将一个工厂方法放入三级缓存
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

假设我们有两个类A和B,相互引用。

  1. A的创建过程
    • A通过构造器实例化(对象A-raw)。
    • A将getEarlyBeanReference工厂放入三级缓存(singletonFactories)。
    • 开始填充A的属性,发现需要B b
  2. B的创建过程
    • 容器去创建B。
    • B通过构造器实例化(对象B-raw)。
    • B将自身的工厂放入三级缓存。
    • 开始填充B的属性,发现需要A a
    • 关键点:B去调用getBean("a")获取A的依赖。在getSingleton方法中,一级缓存没有,二级缓存没有,但在三级缓存中找到了A的工厂。
    • 执行工厂的getObject()方法(即getEarlyBeanReference),获取A的早期引用(可能是一个AOP代理,也可能是原始对象A-raw)。这个早期引用被放入二级缓存(earlySingletonObjects),并从三级缓存移除。
    • B成功获取到A的引用(虽然此时的A还没有完成属性填充和初始化,但引用是有效的)。
    • B继续完成自己的属性填充和初始化,将自己作为一个成品放入一级缓存。
  3. A的完成
    • B创建完成后,A回到自己的属性填充阶段,成功从一级缓存(或二级缓存)中获取到已完成的B对象。
    • A完成自己的属性填充和初始化,成为成品放入一级缓存。

结论:正是populateBean阶段对依赖的获取,触发了三级缓存的调用,从而打破了死循环。如果没有这个“在属性填充前去三级缓存曝光自己”的机制,构造器注入的循环依赖就永远无法解开。

8. 深入源码的角落:其他机制解析

8.1 依赖检查

populateBean中,checkDependencies用于验证Bean所需的所有依赖(简单类型或对象类型)是否都已填充。如果配置为DEPENDENCY_CHECK_OBJECTS,但某个对象类型的属性为null,就会抛出异常。这在现代Spring开发中已很少使用,通常由@Autowired(required=true)替代。

8.2 Record类的支持

Spring 5.1+(特别是Spring 6/Spring Boot 3)开始支持Java Record类。Record是不可变数据类,没有setter方法。在populateBean开头有一段特殊逻辑:

java

1
2
3
4
5
6
if (bw.getWrappedClass().isRecord()) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(...);
}
return; // 跳过属性填充
}

这表示Spring会跳过对Record类的属性填充。Record的初始化完全依赖于构造器完成。

9. 总结:一张时序图与设计思想

9.1 核心流程回顾

  1. 入口populateBeandoCreateBean调用。
  2. 否决权postProcessAfterInstantiation决定是否继续。
  3. 传统装配:处理byName/byType,解析依赖放入PropertyValues
  4. 注解注入AutowiredAnnotationBeanPostProcessor执行@Autowired注入。
  5. 依赖检查:校验必须的属性是否存在。
  6. 值解析与应用applyPropertyValues处理引用、集合、类型转换,最终通过BeanWrapper写入目标Bean。

9.2 设计思想提炼

  • 分层处理,职责单一populateBean只负责流程编排,具体的依赖解析(resolveDependency)、值处理(BeanDefinitionValueResolver)、类型转换(TypeConverter)均由专门的组件完成。
  • 开放闭合原则(OCP):通过InstantiationAwareBeanPostProcessor,Spring允许开发者无侵入地扩展属性填充的逻辑(如添加新的注解@Inject)。
  • 策略模式byNamebyType是两种不同的自动装配策略,通过条件判断进行切换。
  • 缓存与性能AutowiredAnnotationBeanPostProcessor缓存注入点元数据;BeanWrapper缓存内省结果;三级缓存解决循环依赖。处处体现了对性能的考量。

从源码角度理解Spring Bean 的属性填充
https://johnjoyjzw.github.io/2024/12/22/从源码角度理解Spring Bean的属性填充/
Author
JiangZW
Posted on
December 22, 2024
Licensed under