前言
上节在谈论Bean的实例化过程时,在说明实例化后阶段时只是粗略地看了一下populateBean
,并未展开分析。本节接着populateBean
开始分析对象赋值阶段的事情。
populateBean其实主要做了以下几件事:
- Bean实例化后回调,来决定是否进行属性赋值 (上节分析过了)
- 对属性进行自动装配
-
InstantiationAwareBeanPostProcessor
属性赋值前回调 - 属性的真正赋值
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
|
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { //省略无关代码 // 1、 Bean实例化后回调,来决定是否进行属性赋值 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return ; } } } } PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null ); //2、对属性进行自动装配 int resolvedAutowireMode = mbd.getResolvedAutowireMode(); 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); //3、InstantiationAwareBeanPostProcessor属性赋值前回调 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 (pvs != null ) { //属性的赋值 applyPropertyValues(beanName, mbd, bw, pvs); } } |
属性自动装配
PropertyValues 对bd中属性的封装,可以理解为bd中属性键值均由其保存,其常用实现类为MutablePropertyValues,在BeanDefinition的概述及使用 有介绍其使用,可点击查看
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
//这里的bd是已经执行过合并BeanDefinition操作了 //如果bd存在属性 则获取 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null ); //获取bd的自动注入模式 //注入模式有四种: //1.构造函数注入 2、按照名称注入 3、按照类型注入 4、不注入(默认,依然可能会被注解驱动注入) int resolvedAutowireMode = mbd.getResolvedAutowireMode(); //如果是按名称注入或类型注入时 if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); //按名称注入 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; } |
下面我们分别来大致看下autowireByName
及autowireByType
熟悉下实现原理
autowireByName
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
protected void autowireByName( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { //获取属性名称 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); //遍历属性名称 for (String propertyName : propertyNames) { //如果属性名称已在beanDefinitionMap中,说明其是bd 并已被注册待IoC容器 if (containsBean(propertyName)) { //根据名称获取其bean对象 Object bean = getBean(propertyName); //以键值方法赋值到pvs pvs.add(propertyName, bean); // 这里是维护dependentBeanMap、dependenciesForBeanMap两个集合, // 这里不再展开 在说到LifecycleProcessor时再展开 registerDependentBean(propertyName, beanName); //省略日志输出 } else { //省略日志输出 } } } |
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
|
protected void autowireByType( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { //类型转换器 TypeConverter converter = getCustomTypeConverter(); if (converter == null ) { converter = bw; } 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()) { MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered); DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); //解析依赖 Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); if (autowiredArgument != null ) { //以键值方法赋值到pvs pvs.add(propertyName, autowiredArgument); } for (String autowiredBeanName : autowiredBeanNames) { // 这里是维护dependentBeanMap、dependenciesForBeanMap两个集合, // 这里不再展开 在说到LifecycleProcessor时再展开 registerDependentBean(autowiredBeanName, beanName); //省略日志输出 } autowiredBeanNames.clear(); } } catch (BeansException ex) { //省略异常信息 } } |
接下来我们进入到resolveDependency
,大致分析下解析依赖的主要流程
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
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
|
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); //如果依赖类型是Optional if (Optional. class == descriptor.getDependencyType()) { return createOptionalDependency(descriptor, requestingBeanName); } //如果依赖类型是ObjectFactory或ObjectProvider else if (ObjectFactory. class == descriptor.getDependencyType() || ObjectProvider. class == descriptor.getDependencyType()) { return new DependencyObjectProvider(descriptor, requestingBeanName); } //如果依赖类型是Inject 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; } } @Nullable public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); try { Object shortcut = descriptor.resolveShortcut( this ); if (shortcut != null ) { return shortcut; } //获取依赖类型 Class<?> type = descriptor.getDependencyType(); //获取依赖类型的默认值,如@Value注解 可提供默认值 Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null ) { //如果默认值是String类型 if (value instanceof String) { //从配置文件中解析出指定key的数据 String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null ); value = evaluateBeanDefinitionString(strVal, bd); } //类型转换器 用于转换类型,如配置文件中声明的是字符串类型的数字,而java中使用Integer接收,则类型转换器就派上用场了 TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } //解析出类型是Stream、Map、数组、Collection等集合类型的依赖。解析的思路很类似 即去IoC容器中 查找集合类实际泛型对应的Bean Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null ) { return multipleBeans; } //这里主要是查找单实例Bean的,如果某个类型的Bean有多个,这里会被全部查找出来,因此使用Map接收 Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } return null ; } String autowiredBeanName; Object instanceCandidate; //如果查找出的Bean有多个, if (matchingBeans.size() > 1 ) { //找出标注了@Primary的那个Bean名称,作为查找出的Bean autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor); if (autowiredBeanName == null ) { if (isRequired(descriptor) || !indicatesMultipleBeans(type)) { //如果没有@Primary注解标注,那么抛出NoUniqueBeanDefinitionException return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans); } else { return null ; } } instanceCandidate = matchingBeans.get(autowiredBeanName); } else { //如果查找出的Bean只有1个 那么说明找到了。 Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); autowiredBeanName = entry.getKey(); instanceCandidate = entry.getValue(); } if (autowiredBeanNames != null ) { autowiredBeanNames.add(autowiredBeanName); } if (instanceCandidate instanceof Class) { instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this ); } Object result = instanceCandidate; if (result instanceof NullBean) { if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } result = null ; } if (!ClassUtils.isAssignableValue(type, result)) { throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass()); } return result; } finally { ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint); } } |
可以看出resolveDependency
方法还是很强大的,无论是单一类型对象还是集合类型对象,无论是Optional类型还是延迟加载ObjectFactory类型 其均可以解析出来。
属性赋值前回调
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
|
//boolean值 判断有没有InstantiationAwareBeanPostProcessor存在 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); // 这是 是否依赖检查的标记 不是我们此次的重点 boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null ; //IoC容器中如果存在InstantiationAwareBeanPostProcessor if (hasInstAwareBpps) { if (pvs == null ) { pvs = mbd.getPropertyValues(); } //遍历BeanPostProcessor,找到InstantiationAwareBeanPostProcessor类型 for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; //postProcessProperties、postProcessPropertyValues两个方法含义类似。如果postProcessProperties未被重写 则执行postProcessPropertyValues方法 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; } } } |
这里针对一个小案例说明下postProcessPropertyValues
和postProcessProperties
的使用
需求:将注入的user对象中name属性由wojiushiwo修改为abc
实体对象User
1
2
3
4
5
6
7
8
9
10
11
12
|
@Data @ToString public class User { private String name; private Integer age; public User() { } public User(String name, Integer age) { this .name = name; this .age = age; } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public class MyInstantiationBeanPostProcessor implements InstantiationAwareBeanPostProcessor { @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { if (ObjectUtils.nullSafeEquals( "user" ,beanName) && User. class .equals(bean.getClass())){ final MutablePropertyValues propertyValues; if (pvs instanceof MutablePropertyValues){ propertyValues= (MutablePropertyValues) pvs; } else { propertyValues= new MutablePropertyValues(); } if (propertyValues.contains( "name" )){ propertyValues.removePropertyValue( "name" ); propertyValues.addPropertyValue( "name" , "abcd" ); } return propertyValues; } return null ; } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public class BeanPostProcessDemo { public static void main(String[] args) { BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User. class ); beanDefinitionBuilder.addPropertyValue( "name" , "wojiushiwo" ); beanDefinitionBuilder.addPropertyValue( "age" , 20 ); // 获取 AbstractBeanDefinition AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition(); // 附加属性( beanDefinition.setAttribute( "name" , "我是附加属性" ); // 当前 BeanDefinition 来自哪里(辅助作用) beanDefinition.setSource(BeanPostProcessDemo. class ); DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); beanFactory.addBeanPostProcessor( new MyInstantiationBeanPostProcessor()); // 注册 User 的 BeanDefinition beanFactory.registerBeanDefinition( "user" , beanDefinition); User user = beanFactory.getBean( "user" , User. class ); System.out.println(user); } } |
输出结果:
User(name=abcd, age=20)
属性的真正赋值
1
2
3
4
|
if (pvs != null ) { //将从前面步骤得到的pvs 赋值到beanWrapper中以实现属性赋值,这部分具体源码这里不展开了 applyPropertyValues(beanName, mbd, bw, pvs); } |
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注服务器之家的更多内容!
原文链接:https://blog.csdn.net/zyxwvuuvwxyz/article/details/123271627