注:本系列源码分析基于spring 5.2.2.RELEASE,本文的分析基于 annotation 注解方式,gitee仓库链接:gitee.com/funcy/sprin….
BeanPostProcessor 中文名为 spring bean的后置处理器,区别于 BeanFactoryPostProcessor,BeanPostProcessor 可以对 bean 进行操作。
spring BeanPostProcessor 在bean的创建过程中执行,执行时机如下:
在 bean 的创建过程中,BeanPostProcessor 一共执行过8次:
- 尝试生成代理对象
- 推断构造方法
- 获取注入的属性
- 添加三级缓存
- 是否需要注入属性
- 填充属性
- 初始化前
- 初始化后
本来将会逐一梳理这些过程中执行的BeanPostProcessor。
1. 什么是BeanPostProcessor
梳理BeanPostProcessor前,我们先来看看什么是BeanPostProcessor,代码如下:
public interface BeanPostProcessor {
/**
* 初始化前执行
*/
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
/**
* 初始化后执行
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
}
BeanPostProcessor是一个接口,定义了bean初始前后的一些操作,我们可以实现这个接口,重写它的两个方法,就可以在bean初始化前进行一些处理操作了。
BeanPostProcessor 在 AbstractApplicationContext#registerBeanPostProcessors 中注册。
实际上,BeanPostProcessor还有众多的子接口,这些我们都统称为BeanPostProcessor,本文的主要目的就是梳理这些BeanPostProcessor。
2. BeanPostProcessor梳理
2.1 尝试生成代理对象
- 调用位置:
AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation - 执行方法:
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation AbstractAutoProxyCreator#postProcessBeforeInstantiation:生成代理对象
2.2 推断构造方法
- 调用位置:
AbstractAutowireCapableBeanFactory#determineConstructorsFromBeanPostProcessors - 执行方法:
SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors:推断构造方法
2.3 获取注入的属性
- 调用位置:
AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors - 执行方法:
MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition ApplicationListenerDetector#postProcessMergedBeanDefinition:收集单例的ApplicationListenerAutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition:查找被@Autowired、@Value、@Inject标记的属性与方法CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinition:查找被@Resource标记的属性与方法InitDestroyAnnotationBeanPostProcessor#postProcessMergedBeanDefinition:查找被@PostConstruct、@PreDestroy标记的方法
2.4 添加三级缓存
- 调用位置(方法并没有执行):
AbstractAutowireCapableBeanFactory#doCreateBean - 执行方法:
SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference AbstractAutoProxyCreator#getEarlyBeanReference:提前生成代理对象
2.5 是否需要注入属性
- 调用位置:
AbstractAutowireCapableBeanFactory#populateBean - 执行方法:
InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
2.6 填充属性
- 调用位置:
AbstractAutowireCapableBeanFactory#populateBean - 执行方法:
InstantiationAwareBeanPostProcessor#postProcessProperties AutowiredAnnotationBeanPostProcessor#postProcessProperties:填充被@Autowired、@Value、@Inject标记的属性与方法CommonAnnotationBeanPostProcessor#postProcessProperties:填充被@Resource标记的属性与方法ImportAwareBeanPostProcessor#postProcessProperties:为EnhancedConfiguration实例设置beanFactory
2.7 初始化前
- 调用位置:
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization - 执行方法:
BeanPostProcessor#postProcessBeforeInitialization ApplicationContextAwareProcessor#postProcessBeforeInitialization:调用XxxAware接口的方法BeanValidationPostProcessor#postProcessBeforeInitialization:处理JSR-303校验ImportAwareBeanPostProcessor#postProcessBeforeInitialization:调用ImportAware接口的方法InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization:调用被@PostConstruct标记的方法LoadTimeWeaverAwareProcessor#postProcessBeforeInitialization:调用LoadTimeWeaverAware接口的方法ServletContextAwareProcessor#postProcessBeforeInitialization:调用ServletContextAware接口的方法,设置servletContext与servletConfig
2.8 初始化后
- 调用位置:
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization - 执行方法:
BeanPostProcessor#postProcessAfterInitialization AbstractAdvisingBeanPostProcessor#postProcessAfterInitialization:处理AopInfrastructureBeanAbstractAutoProxyCreator#postProcessAfterInitialization:生成代理对象AdvisorAdapterRegistrationManager#postProcessAfterInitialization:如果当前bean是AdvisorAdapter,则注册ApplicationListenerDetector#postProcessAfterInitialization:如果当前bean是ApplicationListener,则添加到事件监听器中BeanPostProcessorChecker#postProcessAfterInitialization:检查操作,打了个logBeanValidationPostProcessor#postProcessAfterInitialization:处理JSR-303校验JmsListenerAnnotationBeanPostProcessor#postProcessAfterInitialization:处理@JmsListener注解ScheduledAnnotationBeanPostProcessor#postProcessAfterInitialization:处理@Scheduled注解SimpleServletPostProcessor#postProcessAfterInitialization:对Servlet实例,调用方法Servlet#init(ServletConfig)
3. 总结
最后用一个表格来总结这些BeanPostProcessor:
本文原文链接:my.oschina.net/funcy/blog/… ,限于作者个人水平,文中难免有错误之处,欢迎指正!原创不易,商业转载请联系作者获得授权,非商业转载请注明出处。
本系列的其他文章