背景
在开发工作中,会遇到一种场景,做完某一件事情以后,需要广播一些消息或者通知,告诉其他的模块进行一些事件处理,一般来说,可以一个一个发送请求去通知,但是有一种更好的方式,那就是事件监听,事件监听也是设计模式中 发布-订阅模式、观察者模式的一种实现。
场景
例如用户注册后执行 -> ①发送注册成功邮件
不管后面的①执行是否成功,都应保证用户注册功能不受影响。
下面以记录日志为案例做代码演示:
日志model
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class LogParam{
private String logKey;
private String content;
private String ipAddress;
public LogParam(String logKey, String content) {
this.logKey = logKey;
this.content = content;
}
}
日志事件类
import org.springframework.context.ApplicationEvent;
/**
* 事件监听也是设计模式中 发布-订阅模式、观察者模式的一种实现。
*/
public class LogEvent extends ApplicationEvent {
private static final long serialVersionUID = 5637703194739977949L;
private final LogParam logParam;
/**
* Create a new ApplicationEvent.
* @param source the object on which the event initially occurred (never {@code null})
* @param logParam login param
*/
public LogEvent(Object source, LogParam logParam) {
super(source);
this.logParam = logParam;
}
public LogEvent(Object source, String logKey, String content) {
this(source, new LogParam(logKey, content));
}
public LogParam getLogParam() {
return logParam;
}
}
监听器
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;
@EnableAsync
@Component
public class LogEventListener {
/**
* 监听器
* @param event
*/
@EventListener
@Async
public void onApplicationEvent(LogEvent event) {
String logKey = event.getLogParam().getLogKey();
String content = event.getLogParam().getContent();
System.out.println(logKey);
}
}
触发事件监听器
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/log")
public class LogController {
private final ApplicationEventPublisher eventPublisher;
public LogController(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
@RequestMapping("/content")
public String getContent(){
LogEvent logEvent = new LogEvent(this, "logController", "getContent");
eventPublisher.publishEvent(logEvent);
return "success";
}
}