分析Spring-ApplicationListener监听器

本文详细介绍了Spring框架中事件监听机制的实现原理,包括ApplicationListener接口的作用、事件多播器的初始化过程以及事件的注册和发布流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、概述

二、运行流程


一、概述

ApplicationListener接口用来监听容器发布的事件,用来事件驱动模型开发。

在方法上使用@EventListener注解,作用与实现ApplicationListener接口一致,都可用来监听事件。

二、运行流程

2.1 容器在refresh方法的prepareBeanFactory方法中添加了类型为ApplicationListenerDetector的后置处理器。

2.1.1 ApplicationListenerDetector后置处理器主要是用来搜索发现实现了ApplicationListener接口bean(包括innerBean也会被搜索到),将其添加到容器的监听器集合中。

因为innerBean不能通过容器的getBeanNamesForType方法得到,所以在refresh方法registerListeners方法中无法将innerBean监听器添加到多播器中。

innerBean 参考什么是Spring inner beans?_Leon_Jinhai_Sun的博客-优快云博客

2.1.2 在组件创建初始化完成后,调用postProcessAfterInitialization方法,将实现了ApplicationListener接口的组件对象(包括innerBean对象)通过容器的addApplicationListener方法添加到监听器集合中。

2.2 在refresh方法中调用initApplicationEventMulticaster方法,初始化applicationEventMulticaster应用事件多播器(派发器)。事件多播器主要是在容器发布事件时,通过遍历applicationEventMulticaster事件多播器的监听器集合,将事件发布到各个监听器中。

2.2.1 initApplicationEventMulticaster方法中先判断容器是否有组件id为applicationEventMulticaster的事件多播器对象。若是有,则从容器中获取组件对象,并赋值给容器的applicationEventMulticaster属性。

若是没有,则容器会默认创建类型为SimpleApplicationEventMulticaster的对象,并赋值给容器的applicationEventMulticaster属性和添加到容器的单实例集合中。

我们可以自定义创建事件多播器对象,并加入到容器的单实例集合中。

2.3 通过refresh方法的registerListeners方法注册监听器 。

2.3.1 registerListeners方法中,先遍历容器之前存储的applicationListeners监听器集合,调用事件多播器的addApplicationListener方法,将监听器对象添加到事件多播器的defaultRetriever.applicationListeners中。

2.3.2 遍历容器中实现了ApplicationListener接口的listenerBeanNames集合,并添加到事件多播器的defaultRetriever.applicationListenerBeans中。

2.3.3 接着将早期存储的earlyApplicationEvents事件集合通过事件多播器的multicastEvent方法发布事件,将容器的earlyApplicationEvents设置为null。

2.3.4 查看ApplicationEventMulticastermulticastEvent方法,先获取到event事件的类型type,接着调用getApplicationListeners方法获取可以监听该事件event的监听器集合。

2.3.5 在getApplicationListeners方法中,先判断事件多播器的retrieverCache缓存中是否可以找到该事件的监听器集合。若是找到,则直接返回缓存中的监听器集合。

若是找不到,则接着通过retrieveApplicationListeners方法找到可以监听该事件的监听器集合并返回。

2.3.6 在retrieveApplicationListeners方法中,先遍历listenersdefaultRetriever.applicationListeners)​​​​​​,​ 通过supportsEvent方法判断该监听器是否可以监听该事件,若可以,则加入到allListeners集合中。

2.3.6.1  在supportsEvent方法中,先判断监听器是否实现了GenericApplicationListener接口。

若是实现了,则将监听器转换成GenericApplicationListener赋值给smartListener,如ApplicationListenerMethodAdapter(标识@EventListener的方法生成的监听器)实现该接口。

而实现ApplicationListener接口的监听器没实现该接口,所以通过创建GenericApplicationListenerAdapter赋值给smartListener,然后调用GenericApplicationListenersupportsEventType方法。

2.3.6.2 GenericApplicationListener接口实现类如下图。

GenericApplicationListenerAdapter的构造器中,通过resolveDeclaredEventType方法解析监听器,得到监听器可以监听事件的类型。

GenericApplicationListenerAdaptersupportsEventType中,通过isAssignableFrom方法判断eventType监听事件的类型是否是监听器监听事件的类型本身或实现类(继承或实现了监听器监听事件的类型)。若是,则表示该监听器可以监听此事件。

2.3.7 接着listenerBeans集合若是不为空,接着遍历listenerBeans集合,判断allListeners集合是否包含遍历的监听器对象。若是不包含,则通过supportsEvent方法判断监听器是否可以监听该事件,若可以,则将其添加到allListeners集合, 最后返回allListeners集合。

2.3.8 遍历返回的监听器集合,判断事件多播器是否有Executor类型的异步对象。若是有,则通过异步对象异步运行invokeListener方法去运行监听器的onApplicationEvent方法,若是没有,则同步运行监听器的invokeListener方法。

2.4 容器通过preInstantiateSingletons方法,创建并初始化完所有非延迟加载的单实例组件对象后,接着遍历容器的beanDefinitions集合,找到实现SmartInitializingSingleton接口的单实例对象,调用对象的afterSingletonsInstantiated方法。

2.4.1 EventListenerMethodProcessor处理器实现SmartInitializingSingleton接口,该处理器主要是解析@EventListener注解,通过afterSingletonsInstantiated方法的processBean方法将标识@EventListener注解的方法封装成ApplicationListenerMethodAdapter的监听器对象并加入到多播器中。

参考分析事件监听器注解:@EventListener、@TransactionalEventListener_Just-Today的博客-优快云博客

2.5 通过容器发布事件,调用容器的publishEvent方法,参数可以是ApplicationEventObject或它们的子类。 

统一调用了publishEvent(Object event, @Nullable ResolvableType eventType)方法,在该方法中,先判断event是否实现了ApplicationEvent接口,若是有,则转换成ApplicationEvent。若是没有,event则通过创建PayloadApplicationEvent对象来构建ApplicationEvent

接着调用多播器的multicastEvent方法发布事件,流程就是2.3.4节

参考分析事件监听器注解:@EventListener、@TransactionalEventListener_Just-Today的博客-优快云博客

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值