什么是spring event?
Spring Event 是 Spring 框架提供的一种事件驱动编程模型。它允许应用程序中的组件通过发布和监听事件来进行松耦合的交互。这种机制基于观察者设计模式,其中组件可以扮演事件发布者的角色,而其他组件则作为事件监听器来响应这些事件。
以下是 Spring Event 的核心概念:
-
事件(Event):代表应用程序中发生的某个事情。在 Spring 中,通常创建一个扩展
ApplicationEvent
类的自定义类来表示特定的事件。这个类可以携带与该事件相关的信息。 -
事件发布者(Publisher):负责发布事件。在 Spring 应用程序中,任何 Bean 都可以通过注入
ApplicationEventPublisher
接口或者继承ApplicationEventPublisherAware
来获得发布事件的能力,并调用publishEvent
方法来发布事件。 -
事件监听器(Listener):用于监听特定类型的事件。在 Spring 4.2 之前,监听器需要实现
ApplicationListener
接口并重写onApplicationEvent
方法。从 Spring 4.2 开始,可以使用@EventListener
注解来简化监听器的配置。当被监听的事件类型发生时,相应的监听器方法就会被调用。
2.在设计模式中,观察者模式是一个比较常用的设计模式。维基百科解释如下:
FROM https://zh.wikipedia.org/wiki/观察者模式
观察者模式是软件设计模式的一种。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。
此种模式通常被用来实时事件处理系统。
在我们日常业务开发中,观察者模式对我们很大的一个作用,在于实现业务的解耦。以用户注册的场景来举例子,假设在用户注册完成时,需要给该用户发送邮件、发送优惠劵等等操作,如下图所示:
- UserService 在完成自身的用户注册逻辑之后,仅仅只需要发布一个 UserRegisterEvent 事件,而无需关注其它拓展逻辑。
- 其它 Service 可以自己订阅 UserRegisterEvent 事件,实现自定义的拓展逻辑。
友情提示:很多时候,我们会把观察者模式和发布订阅模式放在一起对比。
简单来说,发布订阅模式属于广义上的观察者模式,在观察者模式的 Subject 和 Observer 的基础上,引入 Event Channel 这个中介,进一步解耦。如下图所示:
3. 入门示例
看完一些基础的概念,我们来撸个 Spring 事件机制的入门示例,具体的场景还是以用户注册为例子。新建 lab-54-demo 项目,最终项目如下图:
3.1 UserRegisterEvent
创建 UserRegisterEvent 事件类,继承ApplicationEvent 类,用户注册事件。代码如下:
public class UserRegisterEvent extends ApplicationEvent {/*** 用户名*/private String username;public UserRegisterEvent(Object source) {super(source);}public UserRegisterEvent(Object source, String username) {super(source);this.username = username;}public String getUsername() {return username;}}
3.2 UserService
创建 UserService 类,用户 Service。代码如下:
@Service
public class UserService implements ApplicationEventPublisherAware { // <1>private Logger logger = LoggerFactory.getLogger(getClass());private ApplicationEventPublisher applicationEventPublisher;@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {this.applicationEventPublisher = applicationEventPublisher;}public void register(String username) {// ... 执行注册逻辑logger.info("[register][执行用户({}) 的注册逻辑]", username);// <2> ... 发布applicationEventPublisher.publishEvent(new UserRegisterEvent(this, username));}}
<1>
处,实现 ApplicationEventPublisherAware 接口,从而将 ApplicationEventPublisher 注入到其中。
<2>
处,在执行完注册逻辑后,调用 ApplicationEventPublisher 的 #publishEvent(ApplicationEvent event) 方法,发布3.1 UserRegisterEvent 事件。
3.3 EmailService
创建 EmailService 类,邮箱 Service。代码如下:
@Service
public class EmailService implements ApplicationListener<UserRegisterEvent> { // <1>private Logger logger = LoggerFactory.getLogger(getClass());@Override@Async // <3>public void onApplicationEvent(UserRegisterEvent event) { // <2>logger.info("[onApplicationEvent][给用户({}) 发送邮件]", event.getUsername());}}
<1>
处,实现 ApplicationListener 接口,通过 E
泛型设置感兴趣的事件。
<2>
处,实现 #onApplicationEvent(E event)
方法,针对监听的 UserRegisterEvent 事件,进行自定义处理。
【可以不加】<3>
处,锦上添花,设置 @Async
注解,声明异步执行。毕竟实际场景下,发送邮件可能比较慢,又是非关键逻辑。
此处只举例一个邮件发送服务,其他服务可以自行实现。