背景

在开发工做中,会遇到一种场景,作完某一件事情之后,须要广播一些消息或者通知,告诉其余的模块进行一些事件处理,通常来讲,能够一个一个发送请求去通知,可是有一种更好的方式,那就是事件监听,事件监听也是设计模式中 发布-订阅模式、观察者模式的一种实现。java

观察者模式:简单的来说就是你在作事情的时候身边有人在盯着你,当你作的某一件事情是旁边观察的人感兴趣的事情的时候,他会根据这个事情作一些其余的事,可是盯着你看的人必需要到你这里来登记,不然你没法通知到他(或者说他没有资格来盯着你作事情)。web

对于 Spring 容器的一些事件,能够监听而且触发相应的方法。一般的方法有 2 种,ApplicationListener 接口和**@EventListener** 注解。spring

简介

要想顺利的建立监听器,并起做用,这个过程当中须要这样几个角色:
一、事件(event)能够封装和传递监听器中要处理的参数,如对象或字符串,并做为监听器中监听的目标。
二、监听器(listener)具体根据事件发生的业务处理模块,这里能够接收处理事件中封装的对象或字符串。
三、事件发布者(publisher)事件发生的触发者。

如何使用

自定义事件

@Builder
public class ImPushEvent extends ApplicationEvent {
private ReceiveMessage receiveMessage;

public ImPushEvent(Object source) {
super(source);
}



public ImPushEvent(Object source, ReceiveMessage receiveMessage) {
super(source);
this.receiveMessage = receiveMessage;
}


public ReceiveMessage getReceiveMessage() {
return receiveMessage;
}

public void setReceiveMessage(ReceiveMessage receiveMessage) {
this.receiveMessage = receiveMessage;
}

@Override
public String toString() {
return "ImPushEvent{" +
"receiveMessage=" + receiveMessage +
'}';
}
}

定义事件发布

@Slf4j
@Component
public class ImMsgEventPublisher {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;//事件发送

/**
* 监听事件发送
*
* @param receiveMessage
*/
public void pushEventMsg(ReceiveMessage receiveMessage) {
log.info("im事件监听发送消息啦~,接收到数据:{}", receiveMessage.toString());
this.applicationEventPublisher.publishEvent(new ImPushEvent(this,receiveMessage));
}
}

事件监听

@Slf4j
@Component
public class ImMsgEventListener {
//消息推送开关(默认关闭)
private volatile boolean sendSwitch = false;
//有界队列 默认1000个
private BlockingQueue<ReceiveMessage> imMsgQueue = new ArrayBlockingQueue(1000);


/**
* 消息事件监听,推送im消息推送
*
* @param imPushEvent
*/
@Async("asyncThreadPool")
@EventListener
public void handleImMsgEvent(ImPushEvent imPushEvent) {
if (imPushEvent == null) return;
if (imPushEvent.getReceiveMessage() == null) {
log.info("im 监听到得消息为空");
return;
}
log.info("im 监听到得消息量:{}", imPushEvent.getReceiveMessage().toString());
this.imMsgQueue.add(imPushEvent.getReceiveMessage());

// /TODO 异步处理消息数据(可放入有序队列中依次处理)
log.info("im 监听到消息啦~,消息数量:{}", imMsgQueue.size());
//TODO 业务处理
}

也可以通过实现 ApplicationListener 接口来实现

@Slf4j
@Component
public class ImMsgEventPublisher implements ApplicationListener<StudentEvent> {


@Override
public void onApplicationEvent(ImPushEvent imPushEvent) {

if (imPushEvent == null) return;
if (imPushEvent.getReceiveMessage() == null) {
log.info("im 监听到得消息为空");
return;
}
log.info("im 监听到得消息量:{}", imPushEvent.getReceiveMessage().toString());
this.imMsgQueue.add(imPushEvent.getReceiveMessage());

// /TODO 异步处理消息数据(可放入有序队列中依次处理)
log.info("im 监听到消息啦~,消息数量:{}", imMsgQueue.size());
//TODO 业务处理
}

}