Bean建立过程当中的“实例化”与“初始化”名词spring
BeanPostProcessor : 发生在 BeanDefiniton 加工Bean 阶段. 具备拦截器的含义. 能够拦截BeanDefinition建立Bean的过程, 而后插入拦截方法,作扩展工做.app
InstantiationAwareBeanPostProcessor: 继承于BeanPostProcessor ,因此他也是一种参与BeanDefinition加工Bean过程的BeanPostProcessor拦截器, 而且丰富了BeanPostProcessor的拦截.ide
总的来讲:post
BeanPostProcessor定义的方法是在对象初始化过程当中作处理。 InstantiationAwareBeanPostProcessor定义的方法是在对象实例化过程当中作处理this
1.postProcessBeforeInstantiation 调用时机: BeanDefinition建立Bean的开端是在createBean()方法也就是流水线的开始处。spa
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
...省略
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
复制代码
看这段英文注释: Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.debug
给BeanPostProcessor一个机会去返回一个代理对象. 就是在流水线doCreateBean()生成对象以前, 给用户自定义返回一个对象的机会.设计
再看看resolveBeforeInstantiation(beanName, mbdToUse)是如何处理自定义返回对象的.代理
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
复制代码
2.postProcessAfterInstantiation调用时机code
上文resolveBeforeInstantiation()没有返回bean.则走流水线建立Bean
doCreateBean(beanName, mbdToUse, args)建立对象,会通过**populateBean(beanName, mbd, instanceWrapper)**方法。
populateBean(beanName, mbd, instanceWrapper)依次执行postProcessAfterInstantiation() 与postProcessPropertyValues()
3.postProcessBeforeInitialization调用时机
doCreateBean(beanName, mbdToUse, args)建立对象,会通过**initializeBean(beanName, exposedObject, mbd);**方法。
initializeBean(beanName, exposedObject, mbd); 会首先执行 **postProcessBeforeInitialization()**方法
4.postProcessAfterInitialization
initializeBean(beanName, exposedObject, mbd); 会首先执行 **postProcessAfterInitialization()**方法
实例化--->初始化
会造成两种执行流程完成BeanDefinition 建立Bean.
咱们看出:postProcessBeforeInstantiation必定执行, postProcessAfterInitialization必定执行.
至此:不知道读者是否体会到了InstantiationAwareBeanPostProcessor与BeanPostProcessor接口 以及其定义的4个方法的妙处.
四个方法执行的顺序对理解spring建立流程有着重要意义。
BeanPostProcessor 自己就是一种拦截的设计思想. 拦截的目的就是作额外的操做, 即 扩展。
欢迎你们关注个人公众号【源码行动】,最新我的理解及时奉送。