Spring的9处调用后置处理器

在Sping的整个生命周期中,有9个地方调用后置处理器。这些后置处理器是spring实现自定义功能或者扩展spring的核心所在

一、实例化前

该方法属于InstantiationAwareBeanPostProcessor后置处理器

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

	@Nullable
	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}

	default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		return true;
	}

	@Nullable
	default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
			throws BeansException {

		return null;
	}

	@Deprecated
	@Nullable
	default PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

		return pvs;
	}

}

该方法的意思其实也体现到名字上了,就是在实例化之前做些什么。
如果该方法返回非空,代表整个创建流程提前结束,也就是说后面什么属性设置,bean的初始化等等都不会执行了,所以重写该方法一定要谨慎。这个方法一般会和 applyBeanPostProcessorsAfterInitialization后置结处理器结合使用,这个处理可是实现aop的核心,这个后面在分析。

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;
	}

因为如果你在applyBeanPostProcessorsBeforeInstantiation中返回非空后,后面spring的流程就不会走了,但是如果你有个切面是想代理这个类,那就没有办法了,所以applyBeanPostProcessorsBeforeInstantiation返回非空后会调用applyBeanPostProcessorsAfterInitialization执行aop代理

至于网上说的说法:

如果这里出现了aop的切面类,就会有InstantiationAwareBeanPostProcessor的子处理器进行类的过滤,出现@AspectJ的类标记为不需要代理的类,会被放入map中

我目前不理解,我自己写了一个切面类,结果还是和正常类走相同的流程。

二、实例bean前决定构造器

createBeanInstance中的方法determineConstructorsFromBeanPostProcessors中会调用SmartInstantiationAwareBeanPostProcessor 后置处理器的determineCandidateConstructors方法。

2.1 SmartInstantiationAwareBeanPostProcessor

在这里插入图片描述
该构造器主要就是为了预测最终bean的类型(predicting the eventual type of a processed bean)。

2.2 determineCandidateConstructors

该方法也是此处构造器的真正要做的事情。就是为了决定实例化bean的构造器

private DeptService service;

public DeptController(@Autowired DeptService service){
	this.service = service;
}

比如这种情况,肯定不走默认的构造函数,spring就会在determineCandidateConstructors中决定出这个有参数的构造器,然后创建实例的时候回检查参数是否有@Autowired的,在构造的时候就会把service给创建好

三、刚创建好实例之后

createBeanInstance之后,这个时候bean的属性、初始化方法等等都没有创建好,基本属于空白对象。然后在方法applyMergedBeanDefinitionPostProcessors中执行类MergedBeanDefinitionPostProcessor的后置处理

3.1 MergedBeanDefinitionPostProcessor

在这里插入图片描述
这个类主要用来更改或者丰富bean的定义的元数据信息。

3.2 方法postProcessMergedBeanDefinition

  1. CommonAnnotationBeanPostProcessor:这个是MergedBeanDefinitionPostProcessor 一个重要的子类,在这个类中
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);//主要记录生命周期方法
		InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);//记录@Resource  metadata
		metadata.checkConfigMembers(beanDefinition);
	}

可见主要是为了后面的流程进行的一些辅助动作。

  1. AutowiredAnnotationBeanPostProcessor:另外一个重要的子类。
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);//记录@AutoWired medata
		metadata.checkConfigMembers(beanDefinition);
	}

还是为了后面的流程进行的一些辅助动作。

四、解决循环依赖

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		Object exposedObject = bean;
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
				}
			}
		}
		return exposedObject;
	}

上面这段源码是在创建好bean后,如果开启了循环依赖,那么会执行

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

这个时候就来到了主角 getEarlyBeanReference这里。

可见该后置处理器属于SmartInstantiationAwareBeanPostProcessor,这里到底是做什么呢?

4.1 AbstractAutoProxyCreator

改具体子类实现了SmartInstantiationAwareBeanPostProcessor接口。

public Object getEarlyBeanReference(Object bean, String beanName) {
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		this.earlyProxyReferences.put(cacheKey, bean);
		return wrapIfNecessary(bean, beanName, cacheKey);
	}

这个代码就是返回aop代码的代码。 所以该后置处理器有个功能就是返回aop的代理

五、实例化后

在属性填充方法populateBean

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;
					}
				}
			}
		}

改后置处理器来自InstantiationAwareBeanPostProcessor,调用其中的postProcessAfterInstantiation
改方法功能也简单,就是判断是否进行属性注入。

六 设置属性前

for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						if (filteredPds == null) {
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
							return;
						}
					}
					pvs = pvsToUse;
				}
			}

改后置处理器用在 在工厂将给定的属性值应用到给定bean之前,对给定的属性值进行后处理。你可以进行一些检查,比如某个属性是 “required”的,但是这个属性需要的引用却是空,这个时候可以进行一些检查工作。还有dubbo的注解 @DubboReference这个注解,就是在此处 替换需要注入的类来实现的。

七 执行初始化方法前

if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

改代码是在方法initializeBean中调用的。applyBeanPostProcessorsBeforeInitialization详细调用是

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessBeforeInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

可以看到他的引用是接口BeanPostProcessor这个接口属于顶级接口,他的子类太多了,其中有个出名的是CommonAnnotationBeanPostProcessor 该类的结构图是
在这里插入图片描述
其中他的父类InitDestroyAnnotationBeanPostProcessor是个重点角色,在改类中的postProcessBeforeInitialization方法中就执行了大名鼎鼎的 @PostConstruct 注解的方法。

八 执行初始化方法后

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

鼎鼎大名的aop就是在这里进行实现的。具体的后置处理器是AbstractAutoProxyCreator

九 销毁bean容器的时候调用

具体后置处理器InitDestroyAnnotationBeanPostProcessor
在这里插入图片描述

然后调用的方法是postProcessBeforeDestruction

public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
		LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
		try {
			metadata.invokeDestroyMethods(bean, beanName);
		}
		catch (InvocationTargetException ex) {
			String msg = "Destroy method on bean with name '" + beanName + "' threw an exception";
			if (logger.isDebugEnabled()) {
				logger.warn(msg, ex.getTargetException());
			}
			else {
				logger.warn(msg + ": " + ex.getTargetException());
			}
		}
		catch (Throwable ex) {
			logger.warn("Failed to invoke destroy method on bean with name '" + beanName + "'", ex);
		}
	}

什么是destory方法呢,被javax.annotation.PreDestroy 注解的的方法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值