[TOC]

springboot事件监听机制

一、什么是事件监听机制?

事件监听机制,顾名思义,就是对一个事件进行监听,当有外界刺激作用于该事件时能被捕获并产生相应的响应。

如果你知道设计模式,那么你就知道他和观察者模式非常像,监听器就是在观察事件,如果发生就去做相应的事情。

二、springboot中的事件监听机制

springboot内置了一套非常便捷的事件监听机制的实现,现在我们通过一个简单的案例来了解下他如何使用。

我们需要在调用登录接口的时候做以下两件事。

1、打印登录日志

2、给用户增加积分

2.1 不使用事件监听机制的登录代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 登录
* @param username 用户名
* @param password 密码
* @return /
*/
@PostMapping("login")
public Back<Object> login(String username,String password){
if (username.equals(password)){
USERNAME = username;
}
// 记录日志
this.writeLog();
// 添加积分
this.addIntegral();
return Back.ok();
}

2.2 定义事件

事件的定义只需要继承LoginEventData即可。

继承EventObject也是可以的。

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
/**
* 登录事件
* @author xia17
* @date 2023/2/20
*/
public class LoginEvent extends ApplicationEvent {

public LoginEvent(LoginEventData source) {
super(source);
}

}


/**
* 登录事件数据
* @author xia17
* @date 2023/2/20
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class LoginEventData {

private String username;

private String password;

}

2.3 定义监听器

定义监听器有两种方式,一种是实现ApplicationListener接口,一种是使用注解@EventListener

2.3.1 实现ApplicationListener接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* @author xia17
* @date 2023/2/20
*/
@Slf4j
//@Service
@Order(120)
public class LoginEventListener implements ApplicationListener<LoginEvent> {


@Override
public void onApplicationEvent(LoginEvent event) {
Object source = event.getSource();
LoginEventData loginEventData = (LoginEventData) source;
log.info("监听到用户登录事件发生:username={},password={}",loginEventData.getUsername(),loginEventData.getPassword());
}

}
2.3.2 使用注解@EventListener
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
/**
* @author xia17
* @date 2023/2/20
*/
@Slf4j
@Service
public class LoginCoreEventListener {



@EventListener
@Order(1)
public void callback1(LoginEvent event){
Object source = event.getSource();
LoginEventData loginEventData = (LoginEventData) source;
log.info("监听到用户登录事件发生1:username={},password={}",loginEventData.getUsername(),loginEventData.getPassword());
}

@EventListener
@Order(2)
public void callback2(LoginEvent event){
Object source = event.getSource();
LoginEventData loginEventData = (LoginEventData) source;
log.info("监听到用户登录事件发生2:username={},password={}",loginEventData.getUsername(),loginEventData.getPassword());
}


}

2.3.3 注意

1、监听器必须放入到spring容器中

2、可以使用@Order注解来定义执行顺序

2.4 发布事件

使用容器中的ApplicationEventPublisher类来进行发布。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 发布事件的类
private final ApplicationEventPublisher eventPublisher;

/**
* 登录
* @param username 用户名
* @param password 密码
* @return /
*/
@PostMapping("login")
public Back<Object> login(String username,String password){
if (username.equals(password)){
USERNAME = username;
}
eventPublisher.publishEvent(new LoginEvent(new LoginEventData(username,password)));
return Back.ok();
}