分析事件监听器注解:@EventListener、@TransactionalEventListener

目录

一、概述

二、分析@EventListener

2.4 EventListenerMethodProcessor

2.5 DefaultEventListenerFactory

​2.6 ApplicationListenerMethodAdapter

三、分析@TransactionalEventListener

3.3 TransactionalEventListenerFactory

3.4 ApplicationListenerMethodTransactionalAdapter


一、概述

1.1 @EventListener是用来标识在方法上,使得该方法可以监听事件,在事件发布时调用方法处理事件(作用与实现ApplicationListener接口的事件监听器一样,参考分析Spring-ApplicationListener监听器_Just-Today的博客-CSDN博客)。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第1张图片

@EventListener注解有2个属性设置了别名, 分别是valueclasses,这2个属性是可用来设置监听器监听事件的类型。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第2张图片

要求:

           1、若value()和classes()没有设置值,则标识@EventListener的方法必须有且只能有一个参数

           2、若value()或classes()设置了值,

                 2.1、单个Class值,则标识@EventListener的方法可以不用设置参数。若想要设置一个参数,则参数的类型一定要是Class或Class的父类或接口

                 2.2、多个Class值,官方要求@EventListener的方法一定不要设置参数。若是想要设置一个参数,则参数的类型一定要是所有Class的共同父类或接口。因为在监听事件时,通过反射监听方法处理事件,事件转换成方法参数时,若类型不一致,可能会发生类型转换异常。

1.2 @TransactionalEventListener注解上标识@EventListener注解,相当于继承了@EventListener注解的功能,并添加了新的特性。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第3张图片

二、分析@EventListener

2.1 创建AnnotationConfigApplicationContext容器对象时,在构造器中创建了一个AnnotatedBeanDefinitionReader类型的reader

分析事件监听器注解:@EventListener、@TransactionalEventListener_第4张图片

2.2 在AnnotatedBeanDefinitionReader构造器中调用了AnnotationConfigUtils.registerAnnotationConfigProcessors方法。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第5张图片

2.3 registerAnnotationConfigProcessors方法主要是向容器注册创建了一些组件对象。例如扫描解析配置类的ConfigurationClassPostProcessor解析@Autowired、@Value、@Inject注解的AutowiredAnnotationBeanPostProcessor;解析@Resource注解、@PostConstruct、@PreDestroyCommonAnnotationBeanPostProcessor等。

其中包含类型为EventListenerMethodProcessor的组件和类型为DefaultEventListenerFactory的组件也注册到容器中。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第6张图片

2.4 EventListenerMethodProcessor

EventListenerMethodProcessor是用来解析@EventListener注解,该类实现了SmartInitializingSingletonBeanFactoryPostProcessor接口。

2.4.1 在postProcessBeanFactory方法中,从容器中找到类型为EventListenerFactory的组件对象集合,并利用AnnotationAwareOrderComparatorsort方法进行排序,然后赋值给eventListenerFactories

DefaultEventListenerFactory实现了EventListenerFactory接口,在这里也会被加入到eventListenerFactories集合中。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第7张图片2.4.2 容器利用preInstantiateSingletons方法创建初始化非延迟加载的单实例组件后,遍历beanNames(容器组件名称集合),调用getSingleton方法找到实现SmartInitializingSingleton接口的单实例对象,调用对象的afterSingletonsInstantiated方法。

在此时,EventListenerMethodProcessorafterSingletonsInstantiated方法被调用。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第8张图片

2.4.3 EventListenerMethodProcessorafterSingletonsInstantiated方法中调用processBean方法。分析事件监听器注解:@EventListener、@TransactionalEventListener_第9张图片

2.4.4 在processBean方法中,先根据@EventListener得到key为method,value为EventListenerannotatedMethodsannotatedMethods存储了标识@EventListener的方法和注解的相关信息。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第10张图片

接下来,遍历annotatedMethods的key,遍历之前存于EventListenerMethodProcessor.eventListenerFactoriesEventListenerFactory对象,先通过factorysupportsMethod判断factory是否支持method

若支持,则通过factorycreateApplicationListener方法创建监听器对象。

DefaultEventListenerFactorycreateApplicationListener方法会为标识@EventListener的方法创建类型为ApplicationListenerMethodAdapter的监听器对象,然后将监听器对象加到容器的事件多播器中。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第11张图片

2.5 DefaultEventListenerFactory

DefaultEventListenerFactory实现了EventListenerFactory接口,实现的createApplicationListener方法是为标识@EventListener的方法创建类型为ApplicationListenerMethodAdapter的事件监听器对象,method是标识@EventListener的方法。

2.6 ApplicationListenerMethodAdapter

2.6.1 在ApplicationListenerMethodAdapter构造函数中,通过调用resolveDeclaredEventTypes方法来得到监听器监听事件的类型集合。 

分析事件监听器注解:@EventListener、@TransactionalEventListener_第12张图片进入resolveDeclaredEventTypes方法,标识@EventListener注解的方法若有参数,则只能有一个

分析事件监听器注解:@EventListener、@TransactionalEventListener_第13张图片

若是classes()属性有值,通过遍历classes属性得到监听器监听事件的类型集合。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第14张图片

若是classes()属性没有值,则标识@EventListener注解的监听方法必须有且只能有一个参数,参数的类型就是监听事件的类型。 

分析事件监听器注解:@EventListener、@TransactionalEventListener_第15张图片

2.6.2 ApplicationListenerMethodAdapter实现了GenericApplicationListener接口。

在多播器寻找可以监听事件的监听器时,遍历监听器集合,调用supportsEvent方法。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第16张图片

supportsEvent方法中,将listener监听器转换成GenericApplicationListener,然后调用GenericApplicationListenersupportsEventType方法。 

分析事件监听器注解:@EventListener、@TransactionalEventListener_第17张图片

ApplicationListenerMethodAdapter实现了GenericApplicationListener接口,实现的supportsEventType方法中,遍历declaredEventTypes(监听器监听事件的类型集合),

先通过isAssignableFrom方法判断eventType(发布事件的类型)是否是declaredEventType或者它的实现类(继承或实现declaredEventType)。

若是,则表示该监听器可以监听此发布事件,返回true。

若不是,则接着判断eventType是否是PayloadApplicationEvent或者它的实现类。

若是,则得到PayloadApplicationEventT泛型类型(也就是payload的实际类型),然后通过isAssignableFrom方法判断payloadType是否是declaredEventType或它的实现类。若是,则返回true。

最后若是集合遍历结束,还没找到可以监听发布事件的类型,则继续调用eventType.hasUnresolvableGenerics()方法继续判断。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第18张图片

2.6.3 后续容器发布事件时,调用ApplicationListenerMethodAdapter对象的onApplicationEvent方法,onApplicationEvent方法了调用processEvent方法。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第19张图片

2.6.4 在processEvent方法中,先通过resolveArguments方法得到反射监听器方法所需要的参数args。如果args为null,则shouldHandle方法会返回false,不反射监听器方法处理事件。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第20张图片resolveArguments方法先根据getResolvableType方法得到监听器可以监听发布事件的事件类型,

如果返回null,则直接返回。

若不为null,继续往下进行,若监听器方法没有参数,则直接返回空数组。

如果监听器方法含有参数,继续往下,在判断中,如果declaredEventClass不是ApplicationListener的子类(监听事件的类型是普通的Object类型),且发布事件event的类型是PayloadApplicationEvent或它的子类,则判断PayloadApplicationEventpayload属性和declaredEventClass的关系。若是payloaddeclaredEventClass的实现类,则返回存储payload的对象数组。

最后返回存储event的对象数组。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第21张图片

getResolvableType方法,先判断发布事件的类型是否是PayloadApplicationEvent或它的子类,若是,则获取payloadType(若是发布事件的类型是普通的Object类型,则容器会为Object创建PayloadApplicationEvent对象,payload属性就是普通的Object类型)。

然后遍历监听器监听事件的类型集合,先判断监听事件的类型如果不是ApplicationEvent的子类且payloadType有值、payloadTypedeclaredEventType(监听事件的类型)或它的实现类,则返回declaredEventType 

event(发布事件)是eventClass(监听事件的类型)的实现类,则返回declaredEventType

若是没找到对应的declaredEventType,则最后返回null。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第22张图片

2.6.3 调用doInvoke方法通过反射运行method,也就是标识@EventListener注解的方法。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第23张图片

2.6.4 若doInvoke方法有返回值,也就是标识@EventListener的方法有返回值时,调用handleResult方法继续发布事件。

注意:若方法有返回值,需处理好,否则容易造成一直循环发布同一事件,导致发生异常。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第24张图片

三、分析@TransactionalEventListener

3.1 @TransactionalEventListener注解类上标识了@EventListener注解,说明@TransactionalEventListener拥有@EventListener注解的功能,在EventListenerMethodProcessorafterSingletonsInstantiated方法中会被扫描出来。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第25张图片

3.2 通过@EnableTransactionManagement注解开启注解事务时,会向容器注册类型为ProxyTransactionManagementConfiguration的组件对象,而ProxyTransactionManagementConfiguration继承了AbstractTransactionManagementConfiguration

AbstractTransactionManagementConfiguration通过@Bean注解向容器注册了类型为TransactionalEventListenerFactory的组件。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第26张图片

3.3 TransactionalEventListenerFactory

3.3.1 TransactionalEventListenerFactory实现了EventListenerFactory接口,实现的createApplicationListener方法会为标识@TransactionalEventListener的方法创建类型为ApplicationListenerMethodTransactionalAdapter的对象。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第27张图片3.3.2 在EventListenerMethodProcessorpostProcessBeanFactory方法中,TransactionalEventListenerFactory对象也会被getBeanOfType方法扫描出来,然后通过AnnotationAwareOrderComparator排序器的sort方法排序,之前容器默认添加的DefaultEventListenerFactory对象会排到TransactionalEventListenerFactory后面,并加入到eventListenerFactories集合中。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第28张图片

3.3.3 在EventListenerMethodProcessorprocessBean方法中,遍历eventListenerFactories时,会先遍历到类型为TransactionalEventListenerFactory的对象。

3.3.4 TransactionalEventListenerFactory通过supportsMethod方法判断是否支持method(标识@EventListener、@TransactionalEventListener的方法),

supportsMethod方法支持标识@TransactionalEventListener注解的方法。

3.3.5 若是TransactionalEventListenerFactory支持method,则通过调用TransactionalEventListenerFactorycreateApplicationListener方法,创建类型为ApplicationListenerMethodTransactionalAdapter(继承ApplicationListenerMethodAdapter的监听器对象。(若是没有开启注解事务,则DefaultEventListenerFactory会为标识@TransactionalEventListener的方法创建类型为ApplicationListenerMethodAdapter的对象)

分析事件监听器注解:@EventListener、@TransactionalEventListener_第29张图片

3.4 ApplicationListenerMethodTransactionalAdapter

3.4.1 容器发布事件时,调用ApplicationListenerMethodTransactionalAdapter监听器onApplicationEvent方法。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第30张图片3.4.2 先通过TransactionSynchronizationManager.isSynchronizationActive()判断当前线程是否有正在运行的事务。若是有,则通过createTransactionSynchronization方法创建TransactionSynchronizationEventAdapter对象,然后将synchronization注册到当前线程的事务中。

3.4.2.1 容器会对标识@Transactional的方法生成代理对象,运行标识@Transactional注解的方法时,通过代理对象生成拦截器链,调用TransactionInterceptor拦截器的invoke方法开启事务,运行方法。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第31张图片

3.4.2.2 提交事务时,最终会调用事务管理器AbstractPlatformTransactionManagerprocessCommit方法(详细调用可到源码查看),

processCommit方法中,会先调用prepareForCommit(提交事务之前做一些准备工作)、triggerBeforeCommit(触发事务TransactionSynchronizationbeforeCommit方法)、triggerBeforeCompletion(触发事务TransactionSynchronizationbeforeCompletion方法)。       

分析事件监听器注解:@EventListener、@TransactionalEventListener_第32张图片

3.4.2.3 进入triggerBeforeCommit方法,调用TransactionSynchronizationUtils.triggerBeforeCommit方法。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第33张图片

3.4.2.4 在TransactionSynchronizationUtils.triggerBeforeCommit方法中,会遍历之前存于当前线程的事务同步TransactionSynchronization集合,调用TransactionSynchronizationbeforeCommit方法,

而在之前3.4.2节中,已经将TransactionSynchronizationEventAdapter加入到当前线程的事务同步集合中,所以此时会调用TransactionSynchronizationEventAdapterbeforeCommit方法。

3.4.2.5 TransactionSynchronizationEventAdapterbeforeCommit方法,会先判断@TransactionalEventListener注解的phase值。若是phase等于BEFORE_COMMIT,则调用processEvent方法开始处理事件(参考2.6.2节)。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第34张图片

3.4.2.6 若成功提交事务,则会调用triggerAfterCommit方法触发TransactionSynchronizationAfterCommit方法。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第35张图片而在afterCommit方法中会调用TransactionSynchronizationafterCommit方法,而之前存储的TransactionSynchronizationEventAdapter对象,没重写该方法,默认为空方法。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第36张图片

3.4.2.7 最终不管事务是提交或者回滚,都会调用triggerAfterCompletion方法,传入TransactionSynchronization的状态值(0表示commit提交事务 1表示rollback回滚事务 2表示unknown,可能发生系统error)。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第37张图片通过调用invokeAfterCompletion方法遍历当前线程的TransactionSynchronization集合,调用TransactionSynchronizationafterCompletion方法。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第38张图片

分析事件监听器注解:@EventListener、@TransactionalEventListener_第39张图片TransactionSynchronizationEventAdapterafterCompletion方法被调用。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第40张图片3.4.2.8 判断phasestatus发布事件,例如phase等于TransactionPhase.AFTER_COMMIT,且事务正常提交,status等于STATUS_COMMITTED(0),则通过processEvent方法处理事件。 

3.4.2.9 回滚事务时,最终会调用事务管理器AbstractPlatformTransactionManagerprocessRollback方法(调用步骤与3.9.2节调用processCommit方法差不多,详细可到源码查看)。 

3.4.3 若是当前线程不存在事务,则判断@TransactinalEventListenerfallbackExecution属性是否是true。若是true,则表示若当前线程没有正在运行事务运行,该监听器也会监听事件发布,运行processEvent方法调用方法处理事件。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第41张图片

3.4.4 若是当前线程不存在事务,且fallbackExecution属性为false,则不处理事件。

分析事件监听器注解:@EventListener、@TransactionalEventListener_第42张图片

参考

https://www.jianshu.com/p/22b75f98ed16

你可能感兴趣的:(spring,spring,EventListener)