Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析

使用实例
监听器:

@Component public class TransactionListener {@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) public void handler(TransactionEvent transactionEvent) { System.out.println(transactionEvent.getSource()); } }

带有事务的业务代码:
@Override @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED) public void saveUser() { User user = new User(); userMapper.insert(user); eventPublisher.publishEvent(newTransactionEvent("事务提交后发布事件1")); }

源码:
TransactionalEventListenerFactory: 作用: 这个类用来创建ApplicationListenerMethodTransactionalAdapter对象

Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image 如何被注册到spring容器中 @Bean的方式
AbstractTransactionManagementConfiguration这个类被@Configuration修饰

Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image
下面有个@Bean的方法,创建出TransactionalEventListenerFactory实例

Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image EventListenerMethodProcessor 在AnnotationConfigUtils.registerAnnotationConfigProcessors()方法中会把这个类弄成BeanDefinition,注册到BDRegistry中
Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image 这个类实现EventListenerMethodProcessor接口的postProcessBeanFactory方法,和BeanFactoryPostProcessor接口的afterSingletonsInstantiated(),其他Bean实例化过程中会调用到这两个方法
Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image 创建监听器
在所有bean实例化之后,实现SmartInitializingSingleton接口的Bean,会被调用到实现该接口的
afterSingletonsInstantiated方法。
DefaultListableBeanFactory.preInstantiateSingletons()
Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image 这里EventListenerMethodProcessor调用afterSingletonsInstantiated方法

Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image 从BeanFactoryBean取出所有的BeanName,循环调用processBean方法
Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image processBean方法 从bean的Class对象中找出含有@EventListener注解的方法,存到Map中,
@TransactionListenr方法也会被匹配,因为这个注解里打了@EventListener
Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image 【Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析】如果从Bean的Class对象中,找到了含有@EventListener注解的方法,循环每一个方法,循环调用EventListenerFactory的子类进行,判断是否支持该方法的上的注解
//策略模式,如果支持解析该方法的注解,则调用该factory的createApplicationListener方法创建监听器
  1. TransactionalEventListenerFactory 用来对@TransactionalEventListener修饰的方法创建监听器

    Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
    文章图片
    image
  2. DefaultListenerFactory 用来对@EventListener,@TransactionalEventListener修饰的方法创建监听器
Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image 创建ApplicationListenerMethodTransactionalAdapter对象 Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image 其构造方法将beanName,Class,method对象,赋值到自己的属性中,并把注册抽出来了而已
Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image 创建完监听器对象后,将其加入到Spring的事务管理器中

Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image ApplicationListenerMethodTransactionalAdapter类 Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image
实现了ApplicationListener接口,说明它是一个监听器,前面已经加入到事件管理器中,那么根据实现的onApplicationEvent方法的参数类型,决定响应不同类型的事件
Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image 那么,我们编写的带有@TransactionalEventListener注解的方法会在发布事件之后,就会被调用么?
发布事件 注入ApplicationEventPublisher对象
这就是一个上下文ApplicationContext对象,ApplicationContext实现了ApplicationEventPublisher接口
@Autowired private ApplicationEventPublisher eventPublisher;

发布事件:
Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image 根据时间类型,拿出事件管理器里的监听器,执行onApplicationEvent方法
Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image 这个到ApplicationListenerMethodTransactionalAdapter来执行onApplicationEvent方法
Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image 创建一个了TransactionSynchronization对象,放到了事务管理器中
TransactionSynchronization
  1. 里面持有:event对象
  2. 由被@TransactionalEventListener修饰的方法封装而成的监听器适配器
  3. @TransactionalEventListener的value值(TransactionPhase.AFTER_COMMIT)
Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image 发布事件的话,后面就没了,那么事件的触发在哪里呢?在事务的切面里。
事务提交后,触发事件 事务切面
提交事务后,会调这个方法
Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image 取出存放在TransactionSynchronizationManager事务管理器中的TransactionSynchronization,刚才发布事件的时候,往里面存了的哦
Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image 分别调用TransactionSynchronization对象的afterCompletion方法
Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image 最后从容器中取出我们编写的TransactionListener类型的bean,反射调用它的被@TransactionalEventListener修饰的方法
Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image Spring事务监听器@TransactionalEventListener|Spring事务监听器@TransactionalEventListener 源码解析
文章图片
image 总结
一般的监听器
  1. 实现ApplicationListener接口,实现onApplicationEvent方法,
  2. 用@Componnet修饰,ioc容器启动的时候加入到事件管理器中,获取手动调用上下文对象的addApplicationListener方法加入
  3. 发布事件,随即触发事件
@TransactionalEventListener修饰的监听器
  1. 每一个被该注解修饰的方法都会创建一个监听器(持有method对象和当前类的Class),并加入到事件管理器中
  2. 发布事件时,调用上一步创建的监听器的监听方法,将该监听器和必要的信息封装成对象,放到事务管理器
  3. 由事务切面在提交事务之后,从事务管理器里取出上一步存储的对象,反射调用我们自己的监听方法。
需注意点:
  1. 事务监听方法所在的类一定要注册到spring容器中,如果没被实例化,则不会判断方法中是否存在@TransactionalEventListener注解,不会创建监听器适配器。
  2. 发布事件一定要在被事务管理的代码中。如果在事务范围之外发布事件,事务切面已经结束,则不会去调用监听器适配器中反射调用我们监听方法的方法。

    推荐阅读