doCreateBean
方法里有这样两行:
populateBean(beanName, mbd, instanceWrapper);exposedObject = initializeBean(beanName, exposedObject, mbd);
很明显,它们代表了Bean生命周期的属性设置阶段和初始化阶段,但是到目前为止,我们还没有看到InstantiationAwareBeanPostProcessor
的除了before
以外的另两个方法被调用 。虽然populateBean
方法名看起来就是设置Bean属性了,但我们也只能往下看,没准InstantiationAwareBeanPostProcessor
的另外两个方法在这个populateBean
设置属性之前被调用了呢?
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {// 调用所有InstantiationAwareBeanPostProcessor的BeanPostProcessorif (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {return;}}}// ...}
我日尼玛 , 果然?。。。〗淳涂嫉饔?code>InstantiationAwareBeanPostProcessor的after方法
所以,做个小总结:
- 对于那些
InstantiationAwareBeanPostProcessor
没有拦截(before实例化方法返回null的)的Bean,InstantiationAwareBeanPostProcessor
的after实例化方法也会被调用 - 而对于那些before实例化方法没有返回null的,这个after实例化方法不会走,直接调用了after初始化方法,也就是说把实例化到初始化中间的过程都跳过了
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {// 调用after实例化方法if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {return;}}}// 获取所有属性PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);// 自动注入 , 自动注入是针对pvs的 , 而不是bean本身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;}// 对于所有的InstantiationAwareBeanPostProcessor,调用它们的属性设置方法boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);PropertyDescriptor[] filteredPds = null;if (hasInstAwareBpps) {if (pvs == null) {pvs = mbd.getPropertyValues();}// 对于所有InstantiationAwareBeanPostProcessor,调用它的postProcessProperties方法for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);// 如果该方法返回的新pvs为null,那么再调用postProcessPropertyValuesif (pvsToUse == null) {// 该方法默认返回初始pvspvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {return;}}// 让pvs等于两次BeanProcessor方法调用后返回的pvspvs = pvsToUse;}}// 实际设置Bean属性if (pvs != null) {applyPropertyValues(beanName, mbd, bw, pvs);}}
在这里,我们可以看到,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;}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 详解AQS中的condition源码原理
- 怎么去巴基斯坦去巴基斯坦时需要注意什么(从中国去巴基斯坦怎么去)
- 有到过伊拉克的人吗应该怎么去(从国内怎样到伊拉克)
- 从ObjectPool到CAS指令
- 蜘蛛的丝是从哪里吐出来的?
- .net 温故知新:【8】.NET 中的配置从xml转向json
- iqoo7电池多大_iqoo7电池多少毫安
- 【lwip】08-ARP协议一图笔记及源码实现
- <一>从指令角度了解函数堆栈调用过程
- 【lwip】07-链路层收发以太网数据帧源码分析