概述
BeanPostProcessor,bean的后置处理器,贯串了Bean的整个生命周期,在bean的实例化和初始化前后执行。
用户通过扩展BeanPostProcessor接口,可以干预bean的实例化和初始化过程。
BeanPostProcessor和其4个主要扩展接口的类图如下:
整个bean的生命周期过程中,有九次调用BeanPostProcessor。
很多资料在介绍BeanPostProcessor时,只介绍了第七次和第八次调用,这其实是不完整的。
在研究BeanPostProcessor是,要注意方法名中两个单词:
Instantiation表示实例化,Initialization表示初始化
BeanPostProcessor的九次调用时机
1.AbstractAutowireCapableBeanFactory.createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
第一次调用作用于bean实例化之前,调用InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法和BeanPostProcessor的postProcessAfterInitialization方法。
只有当InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation返回值不为null时,才会调用BeanPostProcessor的postProcessAfterInitialization方法。
postProcessBeforeInstantiation的作用是返回一个可以代替原目标bean的代理bean。如果此方法返回一个非null对象,则不会进行bean的常规创建,直接调用BeanPostProcessor的postProcessAfterInitialization方法,如果返回结果不为null,则直接返回bean。
关于BeanPostProcessor的postProcessAfterInitialization方法,会在第八次调用时介绍。
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
/**
* ...代码段
*/
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//第一次调用beanPostProcessor,InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation和其他.postProcessAfterInitialization
//ImportAwareBeanPostProcessor
//CommonAnnotationBeanPostProcessor
//AutowiredAnnotationBeanPostProcessor
//RequiredAnnotationBeanPostProcessor
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);
}
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
2.AbstractAutowireCapableBeanFactory.createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
第二次调用也是作用于bean的实例化之前,调用SmartInstantiationAwareBeanPostProcessor接口的determineCandidateConstructors方法,作用是决定bean实例化时使用的构造方法。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
/**
* ...代码段
*/
// Candidate constructors for autowiring?
//第二次调用beanPostProcessor,SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors
//ImportAwareBeanPostProcessor
//AutowiredAnnotationBeanPostProcessor
//RequiredAnnotationBeanPostProcessor
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
3.AbstractAutowireCapableBeanFactory.doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
第三次调用作用于bean实例化之后,初始化之前,调用MergedBeanDefinitionPostProcessor接口的postProcessMergedBeanDefinition方法,主要作用是扫描@Autowired和@Value注解,为依赖注入做准备。
4.AbstractAutowireCapableBeanFactory.doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
第四次调用作用于bean实例化之后,初始化之前,调用SmartInstantiationAwareBeanPostProcessor接口的getEarlyBeanReference方法,作用是在循环依赖时提前完成aop。
关于循环依赖,请看循环依赖的文章。
这里的第四次并不是指调用顺序是第四,只是分析源码的时候在第四位而已,实际调用时机可能是第七位。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//第三次调用beanPostProcessor,MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition
//CommonAnnotationBeanPostProcessor
//AutorequiredAnnotationBeanPostProcessor
//ApplicationListenerDetector
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.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//第四次调用beanPostProcessor,SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
5.AbstractAutowireCapableBeanFactory.populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)
第五次调用作用于bean实例化之后,初始化之前,调用InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation方法,作用是判断是否应该对bean进行属性注入,返回false,怎不进行属性注入,并且跳过第六次调用。
6.AbstractAutowireCapableBeanFactory.populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)
第六次调用作用于bean实例化之后,初始化之前,调用InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues方法,作用是进行属性注入。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
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;
//第五次调用beanPostProcessor,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;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
//第六次调用beanPostProcessor,InstantiationAwareBeanPostProcessor.postProcessPropertyValues
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) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
7.AbstractAutowireCapableBeanFactory.initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
第七次调用作用于bean的初始化阶段,调用BeanPostProcessor的postProcessBeforeInitialization方法,作用是调用bean的生命周期回调方法,即通常所说的初始化方法。
关于bean的生命周期回调方法,可以看下spring的官方文档1.6.1章节
从spring2.5开始,有三种方式配置bean的生命周期(这里只讲初始化,不讲销毁):
1,实现InitalizingBean接口重写afterPropertiesSet()方法
2,配置init()方法(配合xml文件)
3,使用@PostConstruct注解
当有多种方式同时配置在不同的方法上时,调用顺序为:
1,使用@PostConstruct注解配置的方法
2,实现InitalizingBean接口重写的afterPropertiesSet()方法
3,配置的init()方法(配合xml文件)
当多种方式配置在同一个方法上时,该方法只会被调用一次
@Component
public class AService implements InitializingBean {
// @Autowired
// BService bService;
public AService() {
System.out.println("constructor from aService");
}
public void aop(){
System.out.println("AService----aop");
}
@PostConstruct
public void postConstructor(){
System.out.println("AService---PostConstruct");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("AService---InitializingBean");
}
public void init(){
System.out.println("AService---init");
}
}
spring推荐使用@PostConstruct注解的方式
BeanPostProcessor的第七次调用的作用就是调用使用@PostConstruct注解配置的初始化方法。
其他的初始化方法,会在第七次掉用之后,第八次调用之前的invokeInitMethods(beanName, wrappedBean, mbd)方法中被调用
8.AbstractAutowireCapableBeanFactory.initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
第八次调用作用于bean初始化之后,调用BeanPostPorcessor的postProcessAfterInitialization方法。
通常情况下aop就是在这里完成代理的。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
//第七次调用beanPostProcessor,所有的.postProcessBeforeInitialization
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//第八次调用beanPostProcessor,所有的.postProcessAfterInitialization
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
进入第八次调用的方法,简单看一下aop是怎么实现的
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//getBeanPostProcessors()的结果中有一个AbstractAutoProxyCreator,这个类中实现的aop
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
AbstractAutoProxyCreator.postProcessAfterInitialization(result, beanName)
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
//注意这个earlyProxyReferences,在循环依赖中起着很大的作用
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
//实现aop的方法
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
AbstractAutoProxyCreator的postProcessAfterInitialization方法中wrapIfNecessary(bean, beanName, cacheKey)才是真正实现aop的地方。
注意这个earlyProxyReferences,这是一个map,这个map在循环依赖中起着重要的作用
private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16);
当存在循环依赖的情况时,aop的情况比较特殊,会提前完成,会在专门讲循环依赖的文章中介绍。