一、前言
文章目录:Spring源码深度解析:文章目录
这篇文章是接着 Spring源码深度解析:八、bean的获取② - getSingleton 的继续分析过程。Spring在 AbstractAutowireCapableBeanFactory#doCreateBean()
方法中,完成了bean的完整创建。而在上篇 Spring源码深度解析:九、bean的获取③ - createBeanInstance 中,完成了Bean的创建,但是属性内容还没有注入,本文就是将bean的属性进行注入的过程。
本文涉及部分 BeanPostProcessor 内容,如需详阅 :Spring源码深度解析:后处理器 BeanPostProcessor
二、属性填充入口- populateBean
AbstractAutowireCapableBeanFactory#doCreateBean()
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// 创建Bean的核心方法 protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // 实例化Bean // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { // 有可能在本Bean创建之前,就有其他Bean把当前Bean给创建出来(比如依赖注入过程中) // 单例情况下清除缓存。这里保存的是 FactoryBean 和 BeanWrapper 的映射关系。 // factoryBeanInstanceCache是在创建其他bean的时候缓存了一下FactoryBean 。 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } // 如果没有缓存,则重新创建 if (instanceWrapper == null) { // 1. 创建Bean实例:根据指定的bean使用对应的策略创建新的实例。如:工厂方法、构造函数自动注入,简单初始化 instanceWrapper = createBeanInstance(beanName, mbd, args); } // 获取bean实例 Object bean = instanceWrapper.getWrappedInstance(); // 获取bean类型 Class<?> beanType = instanceWrapper.getWrappedClass(); // 将目标类型替换成实际生成的类型.纠正了上面说到类型错误(如果存在) if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // 2. 调用 MergedBeanDefinitionPostProcessor 后处理器,后置处理合并后的BeanDefinition // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { // 调用MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition()后处理器的方法。 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. // 3. 判断是否需要提早曝光:单例 & 允许循环依赖 & 当前bean已经正在创建中 // 由于当前bean已经在创建中,本次创建必然是循环引用造成的,所以这里判断是否可以需要提前曝光 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } // 4. 为避免后期循环依赖,在bean初始化完成前将创建实例的ObjectFactory加入工程 -- 解决循环依赖:添加到三级缓存 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { // 5. 对bean进行属性填充,将各个属性值注入,其中如果存在依赖于其他bean的属性,则会递归初始依赖bean populateBean(beanName, mbd, instanceWrapper); // 调用初始化方法,比如 init-method exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } // 6. 进行循环依赖检查 if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); // earlySingletonReference只有在检测到有循环依赖的情况下才会不为空 if (earlySingletonReference != null) { // 如果exposedObject没有在初始化方法中被改变,也就是没有被增强 if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { // 检测依赖 if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } // 因为bean创建后其所依赖的bean一定是已经创建了的。actualDependentBeans不为空说明当前bean创建后其依赖的bean却没有全部创建完,也就说说存在循环依赖。 if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { // 7.根据Scopse 注册bean registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
三、populateBean - 概述
我们先整体的过一下代码,然后再详细解读每一步
AbstractAutowireCapableBeanFactory#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
89
90
91/** * beanName: bean的name * mbd: bean的定义信息 * bw: bean实例的包装类型,里面有bean的实例 */ protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { // 没有属性抛出异常 if (bw == null) { if (mbd.hasPropertyValues()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { // Skip property population phase for null instance. // 跳过属性填充阶段以获取空实例 return; } } // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the // state of the bean before properties are set. This can be used, for example, // to support styles of field injection. // 1. 属性填充判断: // mbd.isSynthetic()是否是整合的 && hasInstantiationAwareBeanPostProcessors()判断是否为InstantiationAwareBeanPostProcessor的类型 // 如果是执行InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()方法 // 给InstantiationAwareBeanPostProcessor最后一次机会在属性设置前来改变bean if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 返回值为是否继续填充bean if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } } PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); int resolvedAutowireMode = mbd.getResolvedAutowireMode(); // 2. 自动装配 :根据名称或类型自动注入 if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } // 后处理器已经初始化 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); // 需要依赖检查 boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { if (pvs == null) { pvs = mbd.getPropertyValues(); } PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { // 3. 成员变量的注入 // 调用了InstantiationAwareBeanPostProcessor.postProcessPropertyValues()方法,来进行设值后处理 for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 调用设值 pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } // 如果需要检查 if (needsDepCheck) { // 依赖检查,对应 depends-on属性,3.0 已弃用 checkDependencies(beanName, mbd, filteredPds, pvs); } } if (pvs != null) { // 4. 将属性应用到bean中 applyPropertyValues(beanName, mbd, bw, pvs); } }
从上看下来,整个流程如下:
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
方法,可以决定程序是否继续进行属性填充。只要有一个,InstantiationAwareBeanPostProcessor
返回return,都会终止属性填充的过程。- 根据注入类型(name或type),提取依赖的bean,并统一存入到
PropertyValues
中。 - 应用
InstantiationAwareBeanPostProcessor.postProcessPropertyValues()
方法,对属性获取完毕填充前对属性的再次处理。 - 将所有
PropertyValues
中的属性填充至BeanWrapper
中。
在这里方法里按照如下顺序调用了后处理器
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
: 是否使用InstantiationAwareBeanPostProcessor
进行属性装配InstantiationAwareBeanPostProcessor.postProcessPropertyValues
:进行属性装配
四、populateBean - 详解
1. 属性填充判断
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// 1. 属性填充判断: // mbd.isSynthetic()是否是整合的 && hasInstantiationAwareBeanPostProcessors()判断是否为InstantiationAwareBeanPostProcessor的类型 // 如果是执行InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()方法 // 给InstantiationAwareBeanPostProcessor最后一次机会在属性设置前来改变bean if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 返回值为是否继续填充bean if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } }
如下,这里调用了InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()
方法来决定是否继续注入属性。该方法正常返回true。如果返回false 则将取消对此bean调用任何后续的InstantiationAwareBeanPostProcessor
方法。
2. 自动装配
在下面这段代码中,对AUTOWIRE_BY_NAME
类型和AUTOWIRE_BY_TYPE
的种类进行自动装配。
1
2
3
4
5
6
7
8
9
10
11
12
13
14// 2. 自动装配 :根据名称或类型自动注入 if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; }
这一段代码的目的是,如果bean
在声明的时候指定了自动注入类型是byName
或者byType
,则会根据这个规则,对bean
内部的排除某些特定的属性后, 进行byName
或者byType
的自动装配。
2.1. 根据名字自动装配 - autowireByName
AbstractAutowireCapableBeanFactory#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
27protected void autowireByName( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { // 寻找bw中需要依赖注入的属性name String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { // 检查缓存bean 中是否有当前bean if (containsBean(propertyName)) { // 递归初始化bean,会调用doGetBean 来 获取bean Object bean = getBean(propertyName); pvs.add(propertyName, bean); // 注册依赖,将依赖关系保存到 Map<String, Set<String>> dependentBeanMapdependentBeanMap中,key是bean,value是转化后的propertyName registerDependentBean(propertyName, beanName); if (logger.isDebugEnabled()) { logger.debug("Added autowiring by name from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + propertyName + "'"); } } else { // 找不到则不处理 if (logger.isTraceEnabled()) { logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName + "' by name: no matching bean found"); } } } }
可以看到,byName
的处理逻辑很简单,一句话概括,获取需要注入的bean然后递归调用getBean获取bean进行注入。 关于unsatisfiedNonSimpleProperties
方法在后面有讲解。
2.1.1. 注册依赖bean - registerDependentBean
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// bean dependent(依赖的集合) : beanName -> 依赖该beanName 的 bean,即 key代表的bean 被value 所依赖 private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64); // bean 被哪些bean依赖 : beanName -> beanName 所依赖的 bean。即 key 依赖于value这些bean private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64); /** * 注册依赖关系的bean */ public void registerDependentBean(String beanName, String dependentBeanName) { // 获取真实的beanName String canonicalName = canonicalName(beanName); // 保存依赖关系。dependentBeanMap: key 被 value 依赖 synchronized (this.dependentBeanMap) { Set<String> dependentBeans = this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8)); if (!dependentBeans.add(dependentBeanName)) { return; } } // bean被哪些bean依赖 dependenciesForBeanMap : key 依赖于bean synchronized (this.dependenciesForBeanMap) { Set<String> dependenciesForBean = this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8)); dependenciesForBean.add(canonicalName); } }
2.1.2. 排除规则 - unsatisfiedNonSimpleProperties
在unsatisfiedNonSimpleProperties
方法中,对Bean
的属性进行了过滤,得到了需要自动装配的属性。我们来详细看看里面的内容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) { Set<String> result = new TreeSet<>(); // 获取bean的property属性 PropertyValues pvs = mbd.getPropertyValues(); // 获取 bw 中的属性描述 PropertyDescriptor[] pds = bw.getPropertyDescriptors(); for (PropertyDescriptor pd : pds) { // if pd属性具有set方法 && 依赖检查中没有被忽略 && 没有被配置成property属性 && 不是简单类型 if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) && !BeanUtils.isSimpleProperty(pd.getPropertyType())) { // 添加到需要装配的集合中 result.add(pd.getName()); } } // 返回需要自动装配的bean集合 return StringUtils.toStringArray(result); }
可以看到过滤条件
- 装配属性具有set 方法: 因为后面的装配是通过set方法装配
- 依赖检查中没有被忽略
- 没有property属性,因为这里property会被单独处理,不需要在这里保存
- 不是简单类型,即不属于Void、void、 Enum、CharSequence、Number、Date、Temporal、URI、URL、Locale、Class 和 八大基本数据类型及其包装类型。可以看到如下代码,ClassUtils.isPrimitiveOrWrapper(type) 判断是type是否属于基本数据类型或者其包装类型。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public static boolean isSimpleValueType(Class<?> type) { return (Void.class != type && void.class != type && (ClassUtils.isPrimitiveOrWrapper(type) || Enum.class.isAssignableFrom(type) || CharSequence.class.isAssignableFrom(type) || Number.class.isAssignableFrom(type) || Date.class.isAssignableFrom(type) || Temporal.class.isAssignableFrom(type) || URI.class == type || URL.class == type || Locale.class == type || Class.class == type)); }
2.2. 根据类型自动装配 - autowireByType
AbstractAutowireCapableBeanFactory#autowireByType()
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
50protected void autowireByType( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { // 获取自定义的类型转换器 TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } Set<String> autowiredBeanNames = new LinkedHashSet<>(4); // 寻找 bw中需要依赖注入的属性name String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { try { // 获取属性描述者 PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); // Don't try autowiring by type for type Object: never makes sense, // even if it technically is a unsatisfied, non-simple property. // 排除Object类型 if (Object.class != pd.getPropertyType()) { // 获取指定属性的 set 方法 MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); // Do not allow eager init for type matching in case of a prioritized post-processor. boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered); DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); // 解析指定beanName的属性所匹配的值,并把解析到的属性名存储在autowiredBeanNames中 // 当属性存在多个封装bean时,如 @Autowired List<Bean> beans,会找到所有的匹配Bean 类型的bean并将其注入。 // 这里的返回值是真正的需要注入的属性, autowiredBeanNames 是需要注入的属性(可能是集合)的names Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); if (autowiredArgument != null) { // 添加到待注入的bean列表中 pvs.add(propertyName, autowiredArgument); } // 注册依赖 for (String autowiredBeanName : autowiredBeanNames) { // 注册依赖关系。操作 dependentBeanMap 和 dependenciesForBeanMap 集合 registerDependentBean(autowiredBeanName, beanName); if (logger.isDebugEnabled()) { logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + autowiredBeanName + "'"); } } autowiredBeanNames.clear(); } } catch (BeansException ex) { throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex); } } }
这里面的主要的逻辑被封装到了resolveDependency()
方法中,我们下面来看看DefaultListableBeanFactory#resolveDependency
方法的具体实现。目前我所知另外调用地方:
AutowiredAnnotationBeanPostProcessor
中注入处理@Autowired
注入的时候也调用了该方法
ConstructorResolver#autowireConstructor
在resolveAutowiredArgument( methodParam, beanName, autowiredBeanNames, converter, fallback);
时也调用了该方法。
2.2.1 解析依赖关系 - resolveDependency
AutowireCapableBeanFactory#resolveDependency()
1
2
3
4
5
6@Nullable Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException; }
DefaultListableBeanFactory#resolveDependency()
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@Override @Nullable 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 Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName); } else { // 处理bean是否懒加载,如果懒加载,创建一个代理对象注入bean Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary( descriptor, requestingBeanName); if (result == null) { // 针对一般类型的通用 result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); } return result; } }
上面的逻辑比较清晰,对一些特殊的类型进行特殊处理,一般的通用处理都会调用 doResolveDependency()
方法。这里我们不去关注特殊类型的处理,下面再来看看
DefaultListableBeanFactory#doResolveDependency()
方法,代码如下。
2.2.1.1 DefaultListableBeanFactory#doResolveDependency()
DefaultListableBeanFactory#doResolveDependency()
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@Nullable public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { // 只有ShortcutDependencyDescriptor实现了resolveShortcut方法,返回了非空值。目前版本代码只在AutowiredFieldElement、 // AutowiredMethodElement类中使用到,也即是说,只有解析@Autowired、@Value注解的元素才会用到,目的是为了将解析结果缓存起来,避免重复解析 InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); try { // 尝试获取缓存 Object shortcut = descriptor.resolveShortcut(this); if (shortcut != null) { // 存在缓存直接返回 return shortcut; } // 获取 依赖的类型 Class<?> type = descriptor.getDependencyType(); // 取值@Value注解中的value属性中的值,这里取出的值是未经修改的值,即带有 ${} 标签的值。如果descriptor未被@Value标注,则返回null Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null) { // 到这里说明属性被@Value注解修饰了,这里是解析@Value注解的逻辑 // 如果value不为null, if (value instanceof String) { // 处理占位符如${},做占位符的替换(不解析SP EL表达式) String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null); // 解析SP EL(如#{}) value = evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); // 类型转换,把解析出来的结果转成type类型 return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } // 对集合类型进行处理,包括,Array、Collection、Map。后面详解 Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null) { // 如果解析出来集合类型,则直接返回 return multipleBeans; } // 调用查找所有类型为type的实例,存放在matchingBeans<beanName, bean> (在resolveMultipleBeans方法中也是核心也是调用该方法)。下面详解 Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { if (isRequired(descriptor)) { // 如果没有找到,并且bean并标注为required=true, 则抛出NoSuchBeanDefinitionException异常 raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } return null; } String autowiredBeanName; Object instanceCandidate; // 如果找到了不止一个匹配的bean,Spring 按照一定规则进行挑选 if (matchingBeans.size() > 1) { // 按以下顺序,找到符合条件的就直接返回 // 1. 挑选出被标识为primary的bean // 2. 挑选标识了@Priority,且先级级最高的bean。可以不标识,一旦标识,不允许同一优先级的存在 // 3. fallback,依赖的名称与matchingBeans中任意一Key匹配 autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor); if (autowiredBeanName == null) { if (isRequired(descriptor) || !indicatesMultipleBeans(type)) { // 非集合类,找到了多个符合条件的Bean,抛出异常 return descriptor.resolveNotUnique(type, matchingBeans); } else { // In case of an optional Collection/Map, silently ignore a non-unique case: // possibly it was meant to be an empty collection of multiple regular beans // (before 4.3 in particular when we didn't even look for collection beans). return null; } } instanceCandidate = matchingBeans.get(autowiredBeanName); } else { // We have exactly one match. // 如果只找到了唯一匹配的元素,则直接使用 Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); autowiredBeanName = entry.getKey(); instanceCandidate = entry.getValue(); } if (autowiredBeanNames != null) { // 将待装配的Bean名称放入autowiredBeanNames集合里 autowiredBeanNames.add(autowiredBeanName); } if (instanceCandidate instanceof Class) { // 这里又去调用 getBean 方法去获取bean instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this); } Object result = instanceCandidate; if (result instanceof NullBean) { if (isRequired(descriptor)) { // 如果 result 是 NullBean类型,且 required = true,则抛出异常 raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } result = null; } // 类型校验,确保类型与解析出来的Bean实例能够匹配 if (!ClassUtils.isAssignableValue(type, result)) { throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass()); } return result; } finally { ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint); } }
1 DefaultListableBeanFactory#determineAutowireCandidate()
doResolveDependency() >>>
DefaultListableBeanFactory#determineAutowireCandidate()
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@Nullable protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) { // 获取类型 Class<?> requiredType = descriptor.getDependencyType(); // 获取primary的候选beanName String primaryCandidate = determinePrimaryCandidate(candidates, requiredType); if (primaryCandidate != null) { return primaryCandidate; } // 获取Priority最高(优先级最高的)beanName String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType); if (priorityCandidate != null) { return priorityCandidate; } // Fallback // 通过回调返回。 for (Map.Entry<String, Object> entry : candidates.entrySet()) { String candidateName = entry.getKey(); Object beanInstance = entry.getValue(); if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) || matchesBeanName(candidateName, descriptor.getDependencyName())) { return candidateName; } } return null; }
2 DefaultListableBeanFactory#resolveMultipleBeans()
这个方法是用来处理 数组、Collection、Map 类型的注入。具体实现如下:
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@Nullable private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) { Class<?> type = descriptor.getDependencyType(); // 如果是 数组类型 if (type.isArray()) { // 确定最终类型 Class<?> componentType = type.getComponentType(); ResolvableType resolvableType = descriptor.getResolvableType(); Class<?> resolvedArrayType = resolvableType.resolve(); if (resolvedArrayType != null && resolvedArrayType != type) { type = resolvedArrayType; componentType = resolvableType.getComponentType().resolve(); } if (componentType == null) { return null; } // 根据属性类型找到beanFactory中所有类型的匹配bean // 返回值构成:key = 匹配的beanName, value = beanName对应的实例化bean,通过getBean(beanName)获取。 Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, new MultiElementDescriptor(descriptor)); // 如果是未找到匹配的bean,则返回null, if (matchingBeans.isEmpty()) { return null; } // 保存所有适配的 beanName if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } // 进行类型转换,将bean转换为对应的type类型。 TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); Object result = converter.convertIfNecessary(matchingBeans.values(), type); if (getDependencyComparator() != null && result instanceof Object[]) { // 排序 Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans)); } return result; } // 对Collection类型的处理,逻辑基本同上,这里不再赘述 else if (Collection.class.isAssignableFrom(type) && type.isInterface()) { Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric(); if (elementType == null) { return null; } Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, new MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) { return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); Object result = converter.convertIfNecessary(matchingBeans.values(), type); if (getDependencyComparator() != null && result instanceof List) { ((List<?>) result).sort(adaptDependencyComparator(matchingBeans)); } return result; } // 对map类型的处理,逻辑类似上面 else if (Map.class == type) { ResolvableType mapType = descriptor.getResolvableType().asMap(); Class<?> keyType = mapType.resolveGeneric(0); if (String.class != keyType) { return null; } Class<?> valueType = mapType.resolveGeneric(1); if (valueType == null) { return null; } Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, new MultiElementDescriptor(descriptor)); if (matchingBeans.isEmpty()) { return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } return matchingBeans; } else { return null; } }
可以看到的是,如果是集合类型,内部的核心方法也是findAutowireCandidates
方法。所以下面还是来看DefaultListableBeanFactory#findAutowireCandidates()
方法。
3 DefaultListableBeanFactory#findAutowireCandidates()
DefaultListableBeanFactory#findAutowireCandidates()
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
53protected Map<String, Object> findAutowireCandidates( @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) { // 根据 Class 类型,找到对应的候选beanName, String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this, requiredType, true, descriptor.isEager()); Map<String, Object> result = new LinkedHashMap<>(candidateNames.length); // 这里我们一般不会涉及。如果注入的是 resolvableDependencies key类型,则会装配成value类型 for (Class<?> autowiringType : this.resolvableDependencies.keySet()) { if (autowiringType.isAssignableFrom(requiredType)) { Object autowiringValue = this.resolvableDependencies.get(autowiringType); autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType); if (requiredType.isInstance(autowiringValue)) { result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue); break; } } } // 遍历候选的beanName for (String candidate : candidateNames) { // 不是自引用 && 允许被注入(autowire-candidate 标签指定) if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) { // 将结果添加到result中 addCandidateEntry(result, candidate, descriptor, requiredType); } } // 如果目前找到的匹配的bean集合为空 && Array || Collection || Map 。即是否表示多个bean的集合类型 if (result.isEmpty() && !indicatesMultipleBeans(requiredType)) { // Consider fallback matches if the first pass failed to find anything... DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch(); for (String candidate : candidateNames) { // 非自引用 && 允许被注入 && (非集合类 || 解析 @Qualifier 注解或者 javax.inject.Qualifier类成功) // 这里开始分析解析的属性是否被 @Qualifier 注解或者 javax.inject.Qualifier类 限定符限定了 if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } // 如果还没找到 if (result.isEmpty()) { // Consider self references as a final pass... // but in the case of a dependency collection, not the very same bean itself. for (String candidate : candidateNames) { // 将自我引用视为最后一步。判断是不是自己引用自己 if (isSelfReference(beanName, candidate) && (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) && isAutowireCandidate(candidate, fallbackDescriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } } } return result; }
findAutowireCandidates() >>>
DefaultListableBeanFactory#addCandidateEntry()
1
2
3
4
5
6
7
8
9
10
11
12
13private void addCandidateEntry(Map<String, Object> candidates, String candidateName, DependencyDescriptor descriptor, Class<?> requiredType) { // 根据类型判断,如果是MultiElementDescriptor,获取后保存到候选列表中 if (descriptor instanceof MultiElementDescriptor || containsSingleton(candidateName)) { Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this); candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance)); } else { // getType 调用了beanFacotory.getBean()方法 candidates.put(candidateName, getType(candidateName)); } }
这里提两点:
- 这里需要注意
resolvableDependencies
。其在DefaultListableBeanFactory#resolvableDependencies()
定义如下,其作用是,当一些其他的类需要装配key类型的bean时,实际装配的类型是key对应的value 类型。
1
2
3
4/** Map from dependency type to corresponding autowired value. */ // key 是映射值,value是实际注入值 private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);
在 Spring默认的代码中,仅仅有八个元素保存到其中,如下:
如下, DemoA2021
默认装配的BeanFactory
类型是DefaultListableBeanFactory
类型:
1
2
3
4
5
6
7
8
9@Data @Data public class DemoA2021 { private DemoB2021 demob; private DemoC2021 democ; private List<Demo> demos; private BeanFactory beanFactory; }
从上面的代码可以看到,Spring寻找合适的bean的要求是一再放宽的 : 非自引用 -> 被 Qualifier 限定符修饰的bean -> 自引用。
autowire-candidate
:xml中在注入bean
的时候有该属性。@Bean
也有对应的属性。其作用是用来标记当前bean
是否会被作为注入的候选bean
。默认值true
:表示其他bean
可以把当前bean
作为属性注入。如果false:表示其他bean
选在注入属性bean
时将忽略当前bean
。这一点在上面的代码中也有体现
3. 成员变量的注入
1
2
3
4
5
6
7
8
9
10
11
12
13// 3. 成员变量的注入 // 调用了InstantiationAwareBeanPostProcessor.postProcessPropertyValues()方法,来进行设值后处理 for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 调用设值 pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } }
这里通过InstantiationAwareBeanPostProcessor
的后处理器的postProcessPropertyValues
方法完成了属性的注入。Spring 默认是通过 AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues()
的实现来完成的属性的注入。
AutowiredAnnotationBeanPostProcessor
中完成了@Autowired
、@Value
注解的自动注入功能。
大概逻辑是,获取被@Autowired
修饰的属性或者方法,如果是属性,则通过getBean()
获取bean并注入,如果是方法,则获取方法参数后,invoke()
方法(调用该方法,因为我们一般写的都是set方法,给属性注入赋值)。
4. applyPropertyValues
AbstractAutowireCapableBeanFactory#applyPropertyValues()
上面只是将属性保存了起来,并未真正设置到bean中,这里设置到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
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
95protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { if (pvs.isEmpty()) { return; } if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) { ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext()); } MutablePropertyValues mpvs = null; List<PropertyValue> original; // 如果pvs 是 MutablePropertyValues 类型的封装 if (pvs instanceof MutablePropertyValues) { mpvs = (MutablePropertyValues) pvs; // 如果 mpv 中的值类型已经转换完毕,则可以直接设置到BeanWrapper中 if (mpvs.isConverted()) { // Shortcut: use the pre-converted values as-is. 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()); } // 获取类型转换器 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; // 遍历属性,将属性转换为对应类的对应属性类型 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; 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(); } // Set our (possibly massaged) deep copy. try { bw.setPropertyValues(new MutablePropertyValues(deepCopy)); } catch (BeansException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Error setting property values", ex); } }
五、关于自动装配
名称 | 定义 |
---|---|
AUTOWIRE_DEFAULT | 默认类型,和 AUTOWIRE_NO 相同。需要自己通过 标签或者 ref 属性来指定需要注入的bean类型 |
AUTOWIRE_NO | 和 AUTOWIRE_DEFAULT 相同 |
AUTOWIRE_BY_NAME | 按照bean名称注入 |
AUTOWIRE_BY_TYPE | 按照bean类型注入 |
AUTOWIRE_AUTODETECT | 已过时 |
1、创建Demo2022:com.wts.DemoA2022
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public class DemoA2022 { private DemoB2022 demob; public DemoB2022 getDemob() { return demob; } public void setDemob(DemoB2022 demob) { this.demob = demob; } public DemoA2022() { } public DemoA2022(DemoB2022 demob) { this.demob = demob; } }
2、创建DemoB2022:com.wts.DemoB2022
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public class DemoB2022 { private DemoC2022 demoC2022; public DemoB2022() { } public DemoB2022(DemoC2022 demoC2022) { this.demoC2022 = demoC2022; } public DemoC2022 getDemoC2022() { return demoC2022; } public void setDemoC2022(DemoC2022 demoC2022) { this.demoC2022 = demoC2022; } }
3、创建DemoC2022:com.wts.DemoC2022
1
2
3public class DemoC2022 { }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--因为 demoA2022 指定了 autowire = byType。所以其内部属性(需要有set方法) 会被按照类型检测自动装配--> <bean id="demoA2022" name="demoA2022" class="com.wts.DemoA2022" autowire="byType"/> <!--demoB2022没有指定 autowire。默认是 no,也是 default。就需要自己通过 <property ref> 来指定对应的bean进行注入--> <bean id="demoB2022" name="demoB20222" class="com.wts.DemoB2022"> <property name="demoC2022" ref="demoC2022"/> </bean> <bean id="demoC2022" name="demoC2022" class="com.wts.DemoC2022"/> </beans>
装配方式可以通过@Bean(autowire = Autowire.BY_NAME)
来指定注入方式。也可以通过xml配置中的 < bean … autowire=“byName”>
来指定,默认是 Autowire.NO
,autowire
指的是当前bean内部引用的属性是以什么方式注入。不过需要注意的是,这个属性已经过时了,Spring并不推荐继续使用。
- AUTOWIRE_DEFAULT & AUTOWIRE_NO :没有特殊指定不会处理bean。如果通过 < property> 标签指定。则会在
AbstractAutowireCapableBeanFactory#populateBean()
方法中完成了解析。 - AUTOWIRE_AUTODETECT :在
AbstractAutowireCapableBeanFactory#createBeanInstance()
中完成了解析。 - AUTOWIRE_BY_TYPE & AUTOWIRE_BY_NAME :在
AbstractAutowireCapableBeanFactory#populateBean()
方法中完成了解析。
六、总结
populateBean 在bean创建结束之后,完成了对 bean属性的注入。根据byName、byType 的不同类型注入有不同的解析方式。
以上:内容部分参考
《Spring源码深度解析》
如有侵扰,联系删除。 内容仅用于自我记录学习使用。如有错误,欢迎指正
最后
以上就是沉默星月最近收集整理的关于Spring源码深度解析:十、bean的属性注入④ - populateBean一、前言二、属性填充入口- populateBean三、populateBean - 概述四、populateBean - 详解五、关于自动装配六、总结的全部内容,更多相关Spring源码深度解析:十、bean的属性注入④内容请搜索靠谱客的其他文章。
发表评论 取消回复