Spring源码分析:BeanPostProcessor

概述

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的情况比较特殊,会提前完成,会在专门讲循环依赖的文章中介绍。

9.先不讲

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值