前言:本篇文章不属于保姆级的,主要是方便自己回忆用的,所以需要阅读者具有一定的Spring源码基础。
总结:
- @TransactionEventListener本质上还是@EventListener,事件的发布还是Spring通用的那一套事件发布机制。
- EventListenerMethodProcessor是一个SmartInitializingSingleton,在所有单例bean注册完以后afterSingletonsInstantiated方法会被调用。
- EventListenerMethodProcessor会挑选出标注了@TransactionEventListener的方法,为其创建监听器适配器,最后添加到Spring容器中的监听器集合中进行统一管理。
- 当发布事件时候,Spring容器会根据事件找到对应的监听器适配器,执行监听方法。
- 为什么叫做适配器呢?这里就体现出适配器的作用了,适配器监听到事件不会立刻执行,而是根据是否存在事务、注解配置,来最终决定如何执行。
- 也就是说,如果存在事务,那么就将事件和监听器封装到事务同步器中,在对应的事务阶段处理事件,其实就是将封装起来,并传递下去,延后监听和执行。监听器真正的作用就是监听并执行,因此这里的延后作用就是监听器适配器来实现的。
下面是关键源码的讲解:
@since 4.2 注解的方式提供的相对较晚,其实API的方式在第一个版本就已经提供了。值得注意的是,在这个注解上面有一个注解:`@EventListener`,所以表明其实这个注解也是个事件监听器。
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
所有的单例bean已经注册完毕以后,开始调用org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated方法来处理一些单例bean注册后的需要做的事情。
org.springframework.context.event.EventListenerMethodProcessor#postProcessBeanFactory
在BFPP的方法被调用的时候,会将容器中所有的org.springframework.context.event.EventListenerFactory监听器工厂保存下来。其实一般就2个,一个是org.springframework.context.event.DefaultEventListenerFactory(处理@EventListener的),另一个就是org.springframework.transaction.event.TransactionalEventListenerFactory(处理@TransactionEventListener的)。
org.springframework.context.event.EventListenerMethodProcessor#afterSingletonsInstantiated
获取BF中所有beanName,然后for循环交给org.springframework.context.event.EventListenerMethodProcessor#processBean方法处理。
org.springframework.context.event.EventListenerMethodProcessor#processBean
根据Class对象找到每个方法,挑选出被@EventListener注解标记的方法,然后交由对应的org.springframework.context.event.EventListenerFactory来创建监听器适配器,并将监听器适配器添加到容器的监听器集合中(当然这里也不一定非要是监听器适配器,创建并添加监听器也行,只不过目前现状都是采用的适配器,如果自己实现监听器,在监听器直接处理也行,只不过由适配器处理更加的灵活,有点类似于代理、委托的感觉)。
org.springframework.transaction.event.TransactionalEventListenerFactory
如果方法上存在@TransactionalEventListener,就会创建对应的监听器适配器org.springframework.transaction.event.ApplicationListenerMethodTransactionalAdapter。
org.springframework.transaction.event.ApplicationListenerMethodTransactionalAdapter#onApplicationEvent
监听到事件以后,如果存在事务则创建一个事务同步器org.springframework.transaction.support.TransactionSynchronization,然后将其注册到当前事务同步器的管理器中,其实就向ThreaLocal添加一个事务同步器。如果不存在,但是设置了无事务也要正常执行,那么就正常发布事件(这里就就类似于@EventListener注解的处理逻辑类似了)。否则什么都不做。
org.springframework.transaction.event.ApplicationListenerMethodTransactionalAdapter.TransactionSynchronizationEventAdapter
事务同步器适配器,定义了事务提交前和事务完成后的处理逻辑。当然这里也会指定这个事务同步器的优先级(事务同步器适配器是和事务事件监听器一一对应的,其实就是事务事件监听器的优先级,也就是在标注了监听器注解的方法上,再标记@Order)。
PS:别看才覆盖了2个方法,那是因为org.springframework.transaction.support.TransactionSynchronizationAdapter适配器已经做了空实现。
其实处理分为2类:
- 事务完成前,因为是事务提交前,所以如果指定要在这个阶段执行,那就是beforeCommit方法。
- 事务完成后,因为afterCompletion方法在事务完成后必定会执行,所以事务完成后执行的阶段,都可以写在这个方法中,还能避免重复执行的问题。
org.springframework.transaction.support.TransactionSynchronization
事务同步器定义了一些方法,这些方法分布在事务处理的各个节点。
org.springframework.transaction.support.TransactionSynchronizationAdapter
事务同步器适配器做了空实现。
org.springframework.transaction.support.TransactionSynchronizationUtils
org.springframework.transaction.support.AbstractPlatformTransactionManager事务管理器中会调用当前这个工具类中的事务同步器中的方法。其实就是获取当前线程中的ThreadLocal中保存的同步器,排序后for循环挨个执行对应的方法。