处理器"/>
Spring的9处调用后置处理器
在Sping的整个生命周期中,有9个地方调用后置处理器。这些后置处理器是spring实现自定义功能或者扩展spring的核心所在
一、实例化前
该方法属于InstantiationAwareBeanPostProcessor
后置处理器
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {@Nullabledefault Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {return null;}default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {return true;}@Nullabledefault PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)throws BeansException {return null;}@Deprecated@Nullabledefault 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
- CommonAnnotationBeanPostProcessor:这个是
MergedBeanDefinitionPostProcessor
一个重要的子类,在这个类中
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);//主要记录生命周期方法InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);//记录@Resource metadatametadata.checkConfigMembers(beanDefinition);}
可见主要是为了后面的流程进行的一些辅助动作。
- AutowiredAnnotationBeanPostProcessor:另外一个重要的子类。
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);//记录@AutoWired medatametadata.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 注解的的方法。
更多推荐
Spring的9处调用后置处理器
发布评论