一.BeanPostProcessor是什么
public interface BeanPostProcessor {
/**
* Apply this BeanPostProcessor to the given new bean instance before any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one;
* if {@code null}, no subsequent BeanPostProcessors will be invoked
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
*/
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
/**
* Apply this BeanPostProcessor to the given new bean instance after any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* In case of a FactoryBean, this callback will be invoked for both the FactoryBean
* instance and the objects created by the FactoryBean (as of Spring 2.0). The
* post-processor can decide whether to apply to either the FactoryBean or created
* objects or both through corresponding {@code bean instanceof FactoryBean} checks.
*
This callback will also be invoked after a short-circuiting triggered by a
* {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
* in contrast to all other BeanPostProcessor callbacks.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one;
* if {@code null}, no subsequent BeanPostProcessors will be invoked
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.FactoryBean
*/
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
BeanPostProcessor是Spring容器的一个扩展点,可以进行自定义的实例化、初始化、依赖装配、依赖检查等流程,即可以覆盖默认的实例化,也可以增强初始化、依赖注入、依赖检查等流程,其javadoc有如下描述:
e.g. checking for marker interfaces or wrapping them with proxies.
大体意思是可以检查相应的标识接口完成一些自定义功能实现,如包装目标对象到代理对象。
我们可以看到BeanPostProcessor一共有两个回调方法postProcessBeforeInitialization和postProcessAfterInitialization,那这两个方法会在什么Spring执行流程中的哪个步骤执行呢?还有目前Spring提供哪些相应的实现呢?
Spring还提供了BeanPostProcessor一些其他接口实现,来完成除实例化外的其他功能,后续详细介绍。
二.通过Spring源码看BeanPostProcessor的作用
AbstractApplicationContext内部使用DefaultListableBeanFactory,且DefaultListableBeanFactory继承AbstractAutowireCapableBeanFactory,因此我们此处分析AbstractAutowireCapableBeanFactory即可。
AbstractAutowireCapableBeanFactory里面创建bean的入口是createBean方法:
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
//1.解析bean的class
Class> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 2.方法重载的准备
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//3.这里执行BeanPostProcessor的第一个扩展点(只有InstantiationAwareBeanPostProcessor接口的实现才会被调用)
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
//4.如果执行第一个扩展点之后获得的bean不为空的时候,直接返回这个bean,就不做下面的操作
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
//5.这里是Spring容器执行创建bean的主要流程
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
AbstractAutowireCapableBeanFactory的resolveBeforeInstantiation的方法:
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) {
//3.1 执行InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation回调方法
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//3.2 如果3.1得到的bean不为空的话,执行InstantiationAwareBeanPostProcessor的postProcessAfterInitialization回调方法 ,如果这一步是空的话,则步骤3以后的流程
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
通过如上代码可以进行实例化的预处理(自定义实例化bean,如创建相应的代理对象)和后处理(如进行自定义实例化的bean的依赖装配)。
AbstractAutowireCapableBeanFactory的doCreateBean方法代码如下:
//这段代码是执行创建bean的主要流程的
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
// 6.通过BeanWrapper实例化Bean
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
//7、执行MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition流程(主要的功能是合并BeanDefination)
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
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.
// 8.及早暴露单例Bean引用,从而允许setter注入方式的循环引用
// 判断这个bean是否存在循环依赖的情况
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
//如果需要提前暴露bean(存在了循环依赖)
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 把这个提前暴露的bean(只进行了实例化,但是没有注入属性)注册到singletonFactory中
addSingletonFactory(beanName, new ObjectFactory
AbstractAutowireCapableBeanFactory的populateBean方法代码如下:
//9.组装bean
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
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.
boolean continueWithPropertyPopulation = true;
//9.1 通过InstantiationAwareBeanPostProcessor扩展点允许自定义装配流程(如@Autowired支持等)
//执行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
//9.2 根据BeanName或者BeanType来进行依赖注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
//9.3 执行InstantiationAwareBeanPostProcessor的postProcessPropertyValues~~~~
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
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) {
//9.4 执行依赖检查
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
//9.5 应用依赖注入
applyPropertyValues(beanName, mbd, bw, pvs);
}
AbstractAutowireCapableBeanFactory的initializeBean方法代码如下:
//10 这里执行的是初始化bean的相关工作
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
//10.1 调用Aware接口注入(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware)
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction
三.总结
通过对Spring源码的解读,我相信大家已经对BeanPostProcessor这个接口有了一定的了解。可以看到BeanPostProcessor基本上贯穿了Spring创建bean的整个生命周期,下面我们对BeanPostProcessor的几个扩展点进行一下总结:
1.resolveBeanClass(mbd, beanName), 解析Bean class,若class配置错误将抛出CannotLoadBeanClassException;
2.mbd.prepareMethodOverrides(), 准备和验证配置的方法注入,若验证失败抛出BeanDefinitionValidationException;
3 Object bean = resolveBeforeInstantiation(beanName, mbd); 第一个BeanPostProcessor扩展点,此处只执行InstantiationAwareBeanPostProcessor类型的BeanPostProcessorBean;
3.1 bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName),执行InstantiationAwareBeanPostProcessor的实例化的预处理回调方法postProcessBeforeInstantiation(自定义的实例化,如创建代理);
3.2 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);执行InstantiationAwareBeanPostProcessor的实例化的后处理回调方法postProcessAfterInitialization(如依赖注入),如果3.1处返回的Bean不为null才执行;
4.如果3处的扩展点返回的bean不为空,直接返回该bean,后续流程不需要执行;
5.Object beanInstance = doCreateBean(beanName, mbd, args),执行spring的创建bean实例的流程;
6 createBeanInstance(beanName, mbd, args), 实例化Bean;
6.1 instantiateUsingFactoryMethod 工厂方法实例化;
6.2 构造器实例化;
6.2.1 如果之前已经解析过构造器;
6.2.1.1 autowireConstructor:有参调用autowireConstructor实例化;
6.2.1.2 instantiateBean:无参调用instantiateBean实例化;
6.2.2 如果之前没有解析过构造器:
6.2.2.1 通过SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors回调方法解析构造器,第二个BeanPostProcessor扩展点,返回第一个解析成功(返回值不为null)的构造器组,如AutowiredAnnotationBeanPostProcessor实现将自动扫描通过@Autowired/@Value注解的构造器从而可以完成构造器注入;
6.2.2.2、autowireConstructor:如果(6.2.2.1返回的不为null,且是有参构造器,调用autowireConstructor实例化;
6.2.2.3、instantiateBean: 否则调用无参构造器实例化;
7 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);第三个BeanPostProcessor扩展点,执行Bean定义的合并,执行MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition回调方法,进行bean定义的合并;
8
addSingletonFactory(beanName, new ObjectFactory
及早暴露单例Bean引用,从而允许setter注入方式的循环引用;
8.1、SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference,第四个BeanPostProcessor扩展点,当存在循环依赖时,通过该回调方法获取及早暴露的Bean实例;
9 populateBean(beanName, mbd, instanceWrapper),装配Bean依赖
9.1 InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation;第五个BeanPostProcessor扩展点,在实例化Bean之后,所有其他装配逻辑之前执行,如果false将阻止其他的InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation的执行和从9.2到9.5的执行,通常返回true;
9.2 autowireByName、autowireByType:根据名字和类型进行自动装配;
9.3 InstantiationAwareBeanPostProcessor的postProcessPropertyValues:第六个BeanPostProcessor扩展点,完成其他定制的一些依赖注入,如AutowiredAnnotationBeanPostProcessor执行@Autowired注解注入,CommonAnnotationBeanPostProcessor执行@Resource等注解的注入,PersistenceAnnotationBeanPostProcessor执行@ PersistenceContext等JPA注解的注入,RequiredAnnotationBeanPostProcessor执行@ Required注解的检查等等;
9.4 checkDependencies:依赖检查;
9.5 applyPropertyValues:应用明确的setter属性注入;
10 exposedObject = initializeBean(beanName, exposedObject, mbd); 执行初始化Bean流程;
10.1 invokeAwareMethods(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware):调用一些Aware标识接口注入如BeanName、BeanFactory;
10.2 BeanPostProcessor的postProcessBeforeInitialization:第七个扩展点,在调用初始化之前完成一些定制的初始化任务,如BeanValidationPostProcessor完成JSR-303 @Valid注解Bean验证,InitDestroyAnnotationBeanPostProcessor完成@PostConstruct注解的初始化方法调用,ApplicationContextAwareProcessor完成一些Aware接口的注入(如EnvironmentAware、ResourceLoaderAware、ApplicationContextAware),其返回值将替代原始的Bean对象;
10.3 invokeInitMethods : 调用初始化方法;
10.3.1 InitializingBean的afterPropertiesSet:调用InitializingBean的afterPropertiesSet回调方法;
10.3.2 通过xml指定的自定义init-method:调用通过xml配置的自定义init-method;
10.3.3 BeanPostProcessor的postProcessAfterInitialization:第八个扩展点AspectJAwareAdvisorAutoProxyCreator(完成xml风格的AOP配置(
11 如果是earlySingleExposure,调用getSingle方法获取Bean实例,
earlySingleExposure =(mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName))
只要单例Bean且允许循环引用(默认true)且当前单例Bean正在创建中,如果是earlySingletonExposure调用getSingleton将触发【8】处ObjectFactory.getObject()的调用,通过【8.1】处的getEarlyBeanReference获取相关Bean;
12 registerDisposableBeanIfNecessary(beanName, bean, mbd): 注册Bean的销毁方法(只有非原型Bean可注册):
12.1 单例Bean的销毁流程
12.1.1 DestructionAwareBeanPostProcessor的postProcessBeforeDestruction : 第九个扩展点,如:InitDestroyAnnotationBeanPostProcessor完成@PreDestroy注解的销毁方法注册和调用;
12.1.2 DisposableBean的destroy:注册/调用DisposableBean的destroy销毁方法;
12.1.3 通过xml指定的自定义destroy-method : 注册/调用通过XML指定的destroy-method销毁方法;
12.1.2 Scope的registerDestructionCallback:注册自定义的Scope的销毁回调方法,如RequestScope,SessionScope等;其流程和【12.1 单例Bean的销毁流程一样】
13、到此Bean实例化、依赖注入、初始化完毕可以返回创建好的bean了。
由此可见,BeanPostProcessor这个接口贯穿了Spring创建单例bean的整个过程,我们在开发过程中可以通过定制化的BeanPostProessor来实现对bean的修改。
该博客转载自https://www.iteye.com/topic/1122937