概述
观察者模式又称为发布/订阅(Publish/Subscribe)模式
观察者设计模式涉及到两种角色:主题(Subject)和观察者(Observer)
Subject模块
Subjec模块有3个主要操作
addObserver():注册添加观察者(申请订阅)
deleteObserver():删除观察者(取消订阅)
notifyObserver():主题状态发生变化时通知所有的观察者对象
Observer模块
Observer模块有1个核心操作update(),当主题Subject状态改变时,将调用每个观察者的update()方法,更新通知。
简单demo:
1.主题接口。
2.观察者接口
3.主题实现类,某某杂志
4.观察者实现类
5.测试
这种方式下,发布者发布消息,订阅者 获取消息,订阅了就能收到消息,没订阅就不能收到消息。上述demo中通过for循环进行消息通知,属于同步通知,可利用spring的事件机制实现异步通知。
Spring的事件机制:
ApplicationEvent:表示事件本身,自定义事件需要继承该类,可以用来传递数据,比如上述操作,我们需要将用户的邮箱地址传给事件监听器。
ApplicationEventPublisher或ApplicationEventMulticaster:事件发送器,通过实现这个接口,来触发事件。ApplicationContext接口继承了ApplicationEventPublisher。
ApplicationListener:事件监听器接口,事件的业务逻辑封装在监听器里面。
总的来说,Spring的事件机制主要包括四个步骤:
1. 编写ApplicationEvent类的子类,这就是我们的事件类。
2. 编写监听器类,这个类要实现ApplicationListener接口。
3. 将将监听器类配置在Spring的容器中(类上加@Component注解)。
4. 调用ApplicationContext的publishEvent()方法来主动触发一个容器事件,或者spring的一些内置事件发生。
测试demo:
1.事件类。实现了ApplicationEvent抽象类。
public class PfmwEvent extends ApplicationContextEvent{
private String data;
private String stationIndexCode;
public PfmwEvent(ApplicationContext source) {
super(source);
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public String getStationIndexCode() {
return stationIndexCode;
}
public void setStationIndexCode(String stationIndexCode) {
this.stationIndexCode = stationIndexCode;
}
}
2.事件监听器。@Async标记为异步方法,会在独立线程中完成运行。
@Component
public class PassengerFlowDataListener implements ApplicationListener<PfmwEvent>{
@Override
@Async("taskExecutor")
public void onApplicationEvent(PfmwEvent pfmwEvent) {
//业务逻辑代码
}
}
3.事件发布。调用ApplicationContext的publishEvent()方法。
@Component("homePage")
public class PfmwPublisher implements PfmwStrategy {
@Autowired
ApplicationContext applicationContext;
//使用发布-订阅模式将数据分别进行处理
@Override
public void dealPfmwData(String data, String stationIndexCode) {
try {
JSONObject jsonObject = JSONObject.parseObject(data);
JSONArray labelData = jsonObject.getJSONArray("currentLabelData");
PfmwEvent pfmwEvent = new PfmwEvent(applicationContext);
pfmwEvent.setStationIndexCode(stationIndexCode);
pfmwEvent.setData(labelData.toJSONString());
//发布事件
applicationContext.publishEvent(pfmwEvent);
} catch (Exception e) {
LOGGER.error("解析客流数据失败",e);
}
}
}
参考文档:
Java设计模式之观察者模式(发布/订阅模式)_程裕强的专栏-CSDN博客_java 订阅模式