在这里,我们可以看到,BeanFactory并没有实际设置属性,而是先用一个pvs数据结构来保存所有待设置的属性,自动注入时也操作的是pvs 。这给了InstantiationAwareBeanPostProcessor
可以对属性值进行二次修改的能力 。
InstantiationAwareBeanPostProcessor
的两个与属性相关的方法都可以返回新的pvs,你可以对原始pvs进行改动 。而postProcessProperties
方法默认返回null
,就是不改动,postProcessPropertyValues
方法默认返回原始pvs,也是不改动 。
稍后,BeanFactory会把pvs应用到Bean中 。
postProcessProperties方法的实战#这里,我们检测如果pvs中有名为operator
的属性要设置,我们就创建一个新的pvs,并覆盖它的operator
属性,并返回它,否则我们返回null,也就是不覆盖属性:
@Overridepublic PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {if (pvs.contains("operator")) {MutablePropertyValues clonedPvs = new MutablePropertyValues(pvs);clonedPvs.addPropertyValue("operator", new Person("修改了pvs之后的person"));return clonedPvs;}return null;}
结果,由于autowire阶段Person已经被创建了,所以结果中person的实例化阶段也被打印了:
[+] > MyInstantiationProcessor before bean instantiation : workbench => top.yudoge.springserials.basic.beanfactory.beans.Workbench[+] > MyInstantiationProcessor before bean instantiation : person => top.yudoge.springserials.basic.beanfactory.beans.PersonWorkbench(operator=Person(name=修改了pvs之后的person))
由于我不了解直接修改原始pvs会不会有副作用,所以我选择了克隆一个对象这两个阶段最后的总结#回到这个图上

文章插图
- 从BeanDefinition创建实例化Bean
- 实例化之前如果有
InstantiationAwareBeanPostProcessor
,调用before实例化方法 - 如果并没有一个实例化BeanPostProcessor接管Bean创建,那么进入正常实例化阶段
- 实例化Bean
- 调用
InstantiationAwareBeanPostProcessor
的after实例化方法 - 对pvs进行设置
- 调用
InstantiationAwareBeanPostProcessor
的postProcessProperties方法对pvs进行修改 - 实际的Bean属性设置

文章插图
主要分为几个阶段:
- Aware接口的回调
- BeanPostProcessor的before初始化回调
- 各种初始化方法的回调
- BeanPostProcessor的after初始化回调
// doCreateBean// 属性设置阶段populateBean(beanName, mbd, instanceWrapper);// 初始化阶段exposedObject = initializeBean(beanName, exposedObject, mbd);
进入initalizeBean
,可以看到里面的代码正对应着图中的每一步:protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {// 调用感知方法invokeAwareMethods(beanName, bean);// 调用BeanPostProcessor的before初始化方法Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}// 调用自定义初始化方法try {invokeInitMethods(beanName, wrappedBean, mbd);}// 调用BeanPostProcessor的after初始化方法catch (Throwable ex) {}if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;}
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2023年农历八月初一砍树吉日 2023年9月15日砍树好吗
- 2023年9月15日买宠物好不好 2023年9月15日买宠物好吗
- 2023年9月15日是买狗的黄道吉日吗 2023年9月15日买狗黄道吉日
- 2023年9月15日买猫行吗 2023年9月15日是买猫吉日吗
- 2023年1月28日买牛好吗 2023年1月28日是买牛吉日吗
- 2023年农历八月初一买鸡吉日 2023年9月15日买鸡好不好
- 2023年9月15日是买鸭吉日吗 2023年农历八月初一买鸭吉日
- 2023年农历正月初七买猫吉日 2023年1月28日适合买猫吗
- 2023年农历正月初七宜砍树吗 2023年1月28日砍树吉日一览表
- 2023年1月28日适合塑绘吗 2023年1月28日塑绘黄道吉日