文章目录
- 机制
- 定义event 被观察者
- 定义listener 观察者
- 发布事件 controller或者service中代码
- 为什么要用事件
- 这里的解耦是谁和谁的解耦?
- 是串行还是并行的
- 会不会重复接收
- 可以实现一对多吗?
- 事件和redis和mq和如何选
spring事件机制笔记、发布和监听。
spring事件用的是观察者模式,最大的好处就是解耦。
机制
ApplicationListener # 简称listener,业务listener
ApplicationEvent # 简称event,业务event
ApplicationEventPublisher # 简称publisher,业务代码中注入使用
1、spring的listener本身就是基于事件监听的。
2、当publisher.publishEvent()发布事件时,会根据事件类型到listeners里去匹配,匹配到之后调用listener.onApplicationEvent()来调用处理方法。
定义event 被观察者
代码:
publicclassUserEventextendsApplicationEvent{privateIntegertype;publicUserEvent(Objectsource){super(source);}publicIntegergetType(){returntype;}publicvoidsetType(Integertype){this.type=type;}}注:source是必须的,type是自定义的,当然也可以定义多个属性。
定义listener 观察者
代码:
@Slf4j@Component@EnableAsyncpublicclassUserListenerimplementsApplicationListener<UserEvent>{@Override@Async("asyncUserTaskExecutor")publicvoidonApplicationEvent(UserEventevent){//获取扩展字段参数Map<String,Object>params=(Map<String,Object>)event.getSource();if(1==type){}else{}}}发布事件 controller或者service中代码
代码:
// spring自带,直接注入@AutowiredprivateApplicationEventPublisherapplicationEventPublisher;// 业务方法publicvoidddd(){Map<String,Object>source=newHashMap<>(3);source.put("aaaa","91110113MA01ULE671"));UserEventevent=newUserEvent(source);event.setType(1);applicationEventPublisher.publishEvent(event);// 发布}为什么要用事件
如果不用事件,用代码硬写也是可以的。
但是不优雅,事件完全做到了解耦。
即 发布->消息->接收。
中间是以消息传递的,发布和接收的动作单独完成,实现了解耦。
这里的解耦是谁和谁的解耦?
是事件和业务的解耦吗?
例如下单事件和保存订单信息。
不是,而是事件和监听者的解耦。
例如:
下单业务->发送站内信、发信息给仓库等
是串行还是并行的
默认是串行,加上@EnableAsync和@Async可以实现并行。
会不会重复接收
实测不会,服务内发布,服务内接收,不会跳到其他节点。
可以实现一对多吗?
当然是可以的,多个listener观察者监听同一个事件即可。
如果要新增观察者或者去掉观察者,直接新增或去掉listener即可。
这实现了松耦合,代码比较优雅。
事件和redis和mq和如何选
他们都有通信功能。
| 实现方式 | 描述 |
|---|---|
| event | 解耦、轻量、spring自带。最适合同服务内通信。 |
| redis | 相对重量点,当然redis基本也是标配。更适合跨服务的通信。 |
| mq | 更加重量点,如果没相关业务可以不配置mq。更适合同集团不同系统间通信,例如不同系统间肯定不能用同一个redis,密码也不能互相告诉。用mq就比较合适。 |