Spring Events

1. 概述

事件是框架中最容易被忽视的功能之一,但同时也是一个很有用的功能。像Spring其他特性一样,事件发布是 ApplicationContext
提供的功能之一。

事件通知是一个很有用的功能,使用事件机制可以将互相耦合的代码进行解耦,方便功能的新增或修改。

2. 自定义事件

Spring允许创建和发布自定义事件,默认情况下,事件都是 同步
执行的。这样有很多好处,比如事件的监听器和发布者在同一个事务内,能够很方便的处理一些业务。

2.1. 一个简单的Application Event

创建一个简单的事件类,使用一个 String
变量来存储事件数据

2.2. 事件发布者

现在来创建事件发布者。发布者创建事件对象,并把事件发送给所有的监听器。

要发布事件,发布者可以简单的注入 ApplicationEventPublisher
然后使用它的 publishEvent()
方法:

或者,发布者也可以实现 ApplicationEventPublisherAware
接口。通常情况下使用 @Autowired
注入会更简单。

2.3. 事件监听器

最后,来创建事件监听器。

监听器的唯一要求是一个bean并实现 ApplicationListener
接口:

上面已经说过,默认情况下事件都是 同步执行
的,在所有的监听器完成对事件的处理之前, doStuffAndPublishAnEvent()
方法会一直堵塞。

如果需要指定监听器的执行顺序,可以实现 Ordered
接口设置每个执行器的优先级。

3. 创建异步事件

在某些情况下,同步处理事件并不是我们想要的效果,我们可能需要异步处理事件。

AbstractApplicationContext
中存在一个 ApplicationEventMulticaster
对事件进行广播,默认情况下框架初始化了一个 SimpleApplicationEventMulticaster

SimpleApplicationEventMulticaster
是如何进行事件广播的呢?

如果存在 Executor
,那么事件就会进行异步处理,否则就是同步。

所以需要异步的处理事件,那么就需要手动创建一个name为 applicationEventMulticaster
的bean,然后为它设置一个 TaskExecutor
,例如:

事件、发布者和监听器和前面定义相同,这样监听器就会在单独的线程中异步处理事件。

但是,这样配置的话,所有发布的事件都会以异步的方式进行处理,显然太简单粗暴了,下面介绍一种更加友好的方式。

首先,删除刚刚的 AsynchronousSpringEventsConfig
配置类,然后在Application主类上加上 @EnableAsync
注解,来让程序支持异步方法的调用,最后在监听器的 onApplicationEvent
方法上加上 @Async
注解。

4. 基于注解的事件监听器

从Spring4.2开始,事件监听器不再需要实现 ApplicationListener
接口,可以通过 @EventListener
注解在一个bean的任意public方法上注册:

如果方法需要监听多个事件或者你不想在方法上定义参数,那么你可以在注解里设置事件类型,例如:

注解的 condition
属性可以定义一个SpEL表达式来对事件进行过滤,表达式匹配才能调用特定事件的监听方法。

如果处理完成一个事件后需要发布一个事件,那么你可以在方法上返回相应的事件,例如:

如果需要返回多个事件,那么可以返回事件的集合。

4.1 异步监听器

监听器的异步处理可以通过 @Async
注解来实现。

当使用异步事件监听时,需要注意以下限制:

  • 如果异步事件监听器抛出  Exception
    ,不会将其传播到调用方。可以查看  AsyncUncaughtExceptionHandler
    来获取更多详细信息。

  • 异步事件监听方法无法通过返回值来发布后续事件。如果你确实需要发布后续事件,可以注入  ApplicationEventPublisher
    来手动发布。

4.2 排序监听器

如果需要指定监听器的执行顺序,可以在方法上使用 @Order
注解。

5. 泛型事件

不是所有的事件都必须继承 ApplicationEvent
ApplicationEventPublisher
中有2种方式进行事件的发布。

通过查看实现类代码可以发现,发送的Object类型的事件最后会被包装为一个 PayloadApplicationEvent
,而 PayloadApplicationEvent
继承了 ApplicationEvent

所以我们可以发布任何Object事件。

6. 事务绑定事件

很多时候,只有事务提交之后我们才会发布相应的事件处理其他逻辑,比如用户注册之后,发送邮件或者短信。从Spring 4.2开始,框架提供了一个很方便的注解来实现此功能(4.2之前也可以通过自己写代码实现),即 @TransactionalEventListener

@TransactionalEventListener
是对 @EventListener
的一个扩展,允许将事件的监听器绑定到事务的某个阶段。可以绑定到以下事务阶段:

  • AFTER_COMMIT
    (默认),事务提交后

  • AFTER_ROLLBACK
    ,事务回滚后

  • AFTER_COMPLETION
    ,事务完成,包括提交后和回滚后

  • BEFORE_COMMIT
    ,事务提交前

只有当上下文存在事务,并且事务提交前,才会调用此监听器的方法。

默认情况下,如果上下文不存在事务,则根本不会发送事件,我们可以通过设置 @TransactionalEventListener
fallbackExecution
为true来实现。

原文 

https://mp.weixin.qq.com/s?__biz=MzAwMzg3MjI3MA==&mid=2247483862&idx=1&sn=8f325daf477f1558a7500fce3fd1fc3e&chksm=9b35c2b7ac424ba14a7b7e81910dace1008ea8ed28c16bf056b7945ea2759be03542133cf01d&token=1079721558&lang=zh_CN

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Spring Events

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址