Spring源码学习笔记5——注册BeanPostProcessor,初始化事件多播器,注册事件监听器
一丶前言#
上篇Spring容器回调完所有的BeanFactoryPostPocessor,之后可以做到替换所有占位符,解析所有配置类等工作,这篇还会迎来一个Spring留给我们扩展的一个接口,涉及到Aop的实现
二丶注册BeanPostProcessor后置处理器#
1.什么是BeanPostProcessor#
一个允许自定义修改新 bean 实例的工厂接口,作用是在Bean对象在实例化和依赖注入完毕后,在显示调用初始化方法的前后添加我们自己的逻辑。注意是Bean实例化完毕后及依赖注入完成后触发的
和上篇的 BeanFactoryPostProcessor 名称很像,但是BeanFactoryPostProcessor是针对整个BeanFactory 进行操作,允许我们修改BeanDefinition,注册我们自己的BeanDefinition等,针对一个Bean使用BeanPostProcessor更好,可以为这个Bean生成一个代理
public interface BeanPostProcessor {
// bean实例化但属性没有填充时回调
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
// bean 依赖注入,属性填充后调用
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
2.注册BeanPostProcessor#
处理流程也比较简单,获取BeanFactory中的BeanPostProcessor类型的bean,对于实现PriorityOrdered的BeanPostProcessor,排序并优先放入BeanPostProcessor集合中(通常是一个CopyOnWriteList)先放意味着会先执行,对于实现Ordered的BeanPostProcessor,排序再放入,没有实现Ordered or PriorityOrdered的BeanPostProcessor,不会排序,直接放入(注意这说明BeanPostProcessor的顺序不会受到@Order注解的影响,可能是觉得BeanPostProcessor肯定是需要编写一个类实现接口的,那么继承以下Ordered 和PriorityOrdered吧 )最后对于实现了MergedBeanDefinitionPostProcessor的BeanPostProcessor进行放入,最后把ApplicationListenerDetector放在末尾(笔记三说过这个类,主要是在监听器类型的bean被销毁的时候,会从事件多播器中移除)
3.MergedBeanDefinitionPostProcessor#
MergedBeanDefinitionPostProcessor 的调用是在创建完 bean 实例之后,在 Bean属性填充 之前,将调用 MergedBeanDefinitionPostProcessor 的 postProcessMergedBeanDefinition 方法。
3.1 CommonAnnotationBeanPostProcessor#
解析类中的@Resource,@PostConstruct,@PreDestroy,并且正确的时机执行
其中这个类还实现了 InstantiationAwareBeanPostProcessor,在Bean设置属性的时候,获取@Resouce注解并且进行依赖注入
3.2 AutowiredAnnotationBeanPostProcessor#
解析@Autowrie,和@Value注解,在依赖注入的时候发会作用
还要很多和Bean生命周期相关的接口,贯穿bean的生命周期,这个后续Bean生命周期学习中进行总结
三丶初始化事件多播器#
1.AbstractApplicationContext推送事件#
注意当前容器执行之后还会调用父容器中的监听器响应
2.SimpleApplicationEventMulticaster#
事件多播器的简单实现
2.1 推送事件#
四丶注册事件监听器#
负责把事件监听器 注册到多播器中,并且在事件多播器初始化执行之前,可能存在一些事件没有处理,这些事件都会放在earlyApplicationEvents集合中,在多播器初始化后,会把earlyApplicationEvents置为null 以后的事件都是直接委托给多播器进行推送
1.对于@EventLister的方法是怎么注册#
这种类型的方法被封装成了ApplicationLister,也是在注册事件监听器会注册到多播器中,注册到多播器,存在一个类——EventListenerMethodProcessor负责处理这些方法,在调用所有BeanFactoryPostProcessor的时候会调用到
EventListenerMethodProcessor#
1.1类结构图#
- SmartInitializingSingleton 具有方法 afterSingletonsInstantiated 在bean初始化后会被容器回调使用
1.2 初始化解析Method 生成ApplicationLister的策略#
EventListenerMethodProcessor的 postProcessBeanFactory方法
public interface EventListenerFactory {
//是否可以把当前方法包装成一个 ApplicationListener
boolean supportsMethod(Method method);
// 当前bean的名称 和 标注事件监听注解的方法 生成一个ApplicationListener
ApplicationListener<?> createApplicationListener(String beanName, Class<?> type, Method method);
}
具有两个实现,这EventListenerMethodProcessor使用策略模式,调用者两个类,把符合要求的方法封装成ApplicationLister对象,注册到上下文(上下文会把它们注册到多播器)
1.3把标有@EventLister注册的方法封装成ApplicationListener#
在afterSingletonsInstantiated方法中实现,在bean初始化后会被容器回调使用,获取容器中所有的bean,调用processBean方法把其中标注@EventListener的方法,or @EventListener符合注册的方法,包装一个ApplicationListener 并且注册到上下文中
1.3.1获取具有@EventLister注解的方法#
1.3.2 使用对应的策略生成ApplicationListner
#
超级经典的 策略+工厂+责任链设计模式,妙呀
2.DefaultEventListenerFactory&ApplicationListenerMethodAdapter#
默认的策略,直接new 一个ApplicationListenerMethodAdapter
2.1 ApplicationListenerMethodAdapter构造方法
#
这里的order 来自@Order注解 如果没有注解那么默认最低优先级,这里的condition
2.2 处理事件#
我们可以返回CompletionStage<事件,异常>
会继续推送事件
如果返回的是ListenableFuture(继承了Future)在执行完后进行回调——继续推送事件
3.TransactionalEventListenerFactory&TransactionalApplicationListenerMethodAdapter#
TransactionSynchronizationManager 这个类有点复杂后续详细学习
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~