likes
comments
collection
share

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

作者站长头像
站长
· 阅读数 32

1、概述

2、注册发布原理

springEvent 在refresh spring 上下文中初始化springEvent相关环境。

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

prepareRefresh(spring早期listener和事件准备)

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

2.1、初始化广播器

2.1.1、initApplicationEventMulticaster

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

 

SimpleApplicationEventMulticaster 属性如下:

// 存放listener  
private final DefaultListenerRetriever defaultRetriever = new DefaultListenerRetriever();  
  
// 事件类型与listener关系对应缓存  
final Map<ListenerCacheKey, CachedListenerRetriever> retrieverCache = new ConcurrentHashMap<>(64);

// 异步执行器  
@Nullable  
private Executor taskExecutor;  
  
// 异常事件处理  
@Nullable  
private ErrorHandler errorHandler;

 

DefaultListenerRetriever 属性如下:

// listener bean  
public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();  
  
// listener bean 名称  
public final Set<String> applicationListenerBeans = new LinkedHashSet<>();

2.2、注册监听器

2.2.1、registerListeners

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

2.2.2、实例化 listener Bean

实例化含有【@EventListener】的bean,并添加到 listenerList中

finishBeanFactoryInitialization -> beanFactory.preInstantiateSingletons ->  smartSingleton.afterSingletonsInstantiated() -> EventListenerMethodProcessor.afterSingletonsInstantiated -> processBean

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

2.3、事件发布

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】  

  • 广播事件   multicastEvent

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

  • 获取listener

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

  • 从 retriever 中获取listener

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

  • 判断listener是否支持给定的event

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

  • 执行监听函数

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

3 条件过滤

在注册 @EventListener 注释的listener 方法时,会为方法创建一个代理对象,在代理对象中,维护条件、顺序等信息。在执行 onApplicationEvent 代理方法时,会根据条件判断是否需要执行。

3.1、@EventListener 代理对象

代理对象 GenericApplicationListener

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

GenericApplicationListener 代理含有 @EventListener注释的方法,代理对象在注册listener时创建。

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

3.2、执行onApplicationEvent 代理方法

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

3.3、执行condition

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

04、指定顺序原理

4.1 代理对象继承Order

GenericApplicationListener代理对象继承 Ordered

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

4.2 代理对象实现类重写 getOrde 函数

ApplicationListenerMethodAdapter 实现 GenericApplicationListener 并重写 getOrder 函数,返回order

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

4.3 获取listener时,根据Order排序

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

05、支持事务原理

对含有 @TransactionalEventListener 注释的方法创建代理对象 TransactionalApplicationListenerMethodAdapter,在执行onApplicationEvent方法时创建一个了TransactionSynchronization对象,放到了事务管理器中,事务提交后回调执行方法。

5.1、 TransactionalApplicationListenerMethodAdapter

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

5.2、 创建代理对象并注册

@TransactionalEventListener 注释别名也是 @EventListener,因此在注册时,查询@EventListener时,同样会查询到TransactionalEventListener 注释的方法

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

在  EventListenerMethodProcessor 的  processBean 方法中 创建代理对象

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

TransactionalEventListenerFactory 工厂创建 代理对象

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

5.3、加入事务管理

在TransactionalApplicationListenerMethodAdapter 的  onApplicationEvent 方法中创建TransactionalApplicationListenerSynchronization并放入事务管理器中

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

事务管理 AbstractPlatformTransactionManager,事务提交方法

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

事务提交后调用 processCommit方法,processCommit 最终调用invokeAfterCommit方法。在invokeAfterCommit方法中,调用 TransactionalApplicationListenerSynchronization 里面实现的  afterCompletion 方法

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

06、支持异步原理

Spring容器启动初始化bean时,判断类中是否使用了@Async注解,创建切入点和切入点处理器,根据切入点创建代理,在调用@Async注解标注的方法时,会调用代理,执行切入点处理器invoke方法,将方法的执行提交给线程池,实现异步执行。

6.1 创建代理方法

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

AsyncAnnotationBeanPostProcessor间接实现了BeanFactoryAware接口,所以它在被实例化的时候会执行setBeanFactory方法

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

创建环绕通知  AnnotationAsyncExecutionInterceptor

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

将有 @Async 注释的方法创建切点 Pointcut

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

AsyncAnnotationBeanPostProcessor类间接实现了BeanPostProcessor接口,也就是说在bean初始化之前和之后会分别执行postProcessBeforeInitialization方法和postProcessAfterInitialization方法。

而AsyncAnnotationBeanPostProcessor类的这两个方法是从AbstractAdvisingBeanPostProcessor类中继承来的,这里重点分析AbstractAdvisingBeanPostProcessor的postProcessAfterInitialization方法,具体代码如下:

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

到此,为 @Async注释修饰的方法创建代理对象完成

6.2、方法执行

AnnotationAsyncExecutionInterceptor间接实现了MethodInterceptor接口,而MethodInterceptor是AOP中切入点的处理器,处理器中最终被调用的是invoke方法

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

默认情况下,Spring 将搜索关联的线程池定义:上下文中的唯一 org.springframework.core.task.TaskExecutor bean,或者名为“taskExecutor”的 java.util.concurrent.Executor bean。

如果两者都无法解析,则将使用 org.springframework.core.task.SimpleAsyncTaskExecutor 来处理异步方法调用。

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

事件驱动模型的最佳实践-SpringEvent【(二)原理篇】

7、总结

整体流程还是比较清晰容易梳理,学习完之后对Spring会有更深一层的认识。

转载自:https://juejin.cn/post/7359118871981228084
评论
请登录