Spring事件

本文最后更新于:2025年6月29日 下午

Spring事件

spring事件机制是由发布者和订阅者两部分组成,也就是发布订阅机制,通常只在单体架构中使用。可以将非核心业务解耦出来,例如消息通知,日志记录等。像这种机制,第三方组件也有,例如Redis的发布订阅机制,再者就是消息队列了,例如RabbitMQ,不仅能通过Fanout交换机进行广播,还能通过其他交换机点对点发送,这种就更专业一些了,功能也更强大(例如消息的重复消费,消息持久化等等),这种更适合分布式系统。

整体流程

1、定义事件

2、发布事件

3、接收事件

4、调用并发布事件

相关文档:https://docs.spring.io/spring-framework/docs/5.3.39/reference/html/core.html#context-functionality-events-annotation

Maven依赖

1
2
3
4
5
6
7
8
9
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>

定义事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.events.service;

import lombok.Getter;
import org.springframework.context.ApplicationEvent;

/**
* 登录事件
*
* @author peter
* @date 2025/6/28
*/
@Getter
public class LoginEvent extends ApplicationEvent {

private final String message;

public LoginEvent(Object source, String message) {
super(source);
this.message = message;
}
}

事件发布类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.events.service;

import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

/**
* 登录事件发布者
* @author peter
*/
@Service
public class LoginEventPublisher {

private final ApplicationEventPublisher applicationEventPublisher;

public LoginEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}

public void publishLoginEvent(String username) {
LoginEvent loginEvent = new LoginEvent(this, username);
applicationEventPublisher.publishEvent(loginEvent);
}
}

事件监听类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.events.service;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

/**
* @author peter
*/ // 登录消息通知事件监听器
@Component
public class LoginEventListener {

// 可以添加多个监听器监听同一事件,也可监听多个事件

// 监听多个事件的示例
@EventListener(value ={LoginEvent.class, LoginEvent.class})
@Order(20)// 优先级, 数字越小优先级越高,若需要多个监听器监听同一事件,并规范执行顺序,可使用排序
@Async// 异步处理
public void loginEventListener(ApplicationEvent event) {

if (event instanceof LoginEvent){
LoginEvent loginEvent = (LoginEvent) event;
String username = loginEvent.getMessage();
// 发送消息通知用户
System.out.println("message send User logged in: " + username);
}
// 若一次监听多个事件,就这么继续叠判断事件类型处理。
// 但不推荐这样,尽量使用单个监听器监听单个事件,可以用order来区别优先级

}

// 监听单个事件的示例,条件内可指定监听的消息
@EventListener(condition = "#event.message.equals('peter')")
@Order(10)// 优先级, 数字越小优先级越高,若需要多个监听器监听同一事件,并规范执行顺序,可使用排序
@Async// 异步处理
public void loginEventListener(LoginEvent event) {

String username = event.getMessage();
// 发送消息通知用户
System.out.println("只监听内容是peter的消息: " + username);

}
}

调用发布事件

在这个类中执行的方法,会在启动项目后立即执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.events;

import com.events.service.LoginEventPublisher;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

/**
* @author peter
*/
@Component
public class MyCommandLineRunner implements CommandLineRunner {

private final LoginEventPublisher loginEventPublisher;

public MyCommandLineRunner(LoginEventPublisher loginEventPublisher) {
this.loginEventPublisher = loginEventPublisher;
}

@Override
public void run(String... args) {
// 在应用程序启动后执行的自定义逻辑
System.out.println("MyCommandLineRunner executed!");

// 登录成功
// 登录执行后逻辑
loginEventPublisher.publishLoginEvent("小王");
}
}

Spring事件
https://superlovelace.top/2025/06/29/Spring事件/
作者
棱境
发布于
2025年6月29日
更新于
2025年6月29日
许可协议