1. 前沿
在系统开发的过程中,会有不同对象之间有关联性,如a对象的状态发送了改变,需要改变b对象的状态,如果在同一个方法中编写2个实现逻辑,会导致a和b对象进行紧耦合,无法实现高内聚,这样之后可能需求改变,如果a对象的状态发送了改变,又需要改变c对象的状态,这样需要去更新原来的实现逻辑,又破坏了开闭原则、单一职责原则,因此需要引入springboot的事件监听机制,这样可以让变化与变化进行解耦合,提高各自的高内聚。
2. 使用
事件监听机制,类似设计模式中的观察者模式,当一个状态发送了改变,会通知该类所关联的所有的观察者。
2.1 在springboot中,需要定义一个事件,这个事件就是类似状态,会存储一些监听器所需要的数据。
public class XEvent extends ApplicationEvent {
/**
* 发生库存数量改变的IDs
*/
private List<String> ids;
/**
* Create a new ApplicationEvent.
*
* @param source the object on which the event initially occurred (never {@code null})
* @param drugInventoryChangeDtoList 药品ID
*/
public XEvent(Object source,List<String> ids) {
super(source);
this.ids = ids;
}
public List<String> getIds(){
return ids;
}
}
2.2 定义一个监听器,也就是说当事件进行发布的时候,就会调用监听器的接口方法,因此监听器类需要使用对应的接口方法。
@Component
@Slf4j
public class XListener implements ApplicationListener<XEvent> {
@Resource
private PMapper dyMapper;
/**
* 发生库存数量改变宕药品IDs
*/
private List<String> ids;
@Override
public void onApplicationEvent(XEvent event) {
ids = event.getids();
// 更新库存表
udpate();
}
private void udpate() {
}
}
注意:
- 监听器需要定义成component就是bean,这样才能被Spring进行管理。
2.3 进行发布
发布的时候,是需要spring自带的发布对象。
@Autowired
private ApplicationEventPublisher publisher;
@Transcation
public void sendInsertUser() {
xxx
// 发布事件
publisher.publishEvent(xEvent);
}
3. 事务相关
点进去publishEvent方法可知:
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
Executor executor = getTaskExecutor();
这样会判断该事件通知是否为同步和异步,也就是说事件通知也是支持异步的,默认情况下是同步机制。
这样的话,二个不同方法的事务管理是符合事务传播级别的,也就是在一个事务方法下调用了事件发布,该监听器的方法默认是会随着上一个事务的,二个方法是处于同一个事务管理的。
如果需要异步处理的话,详见:
https://blog.csdn.net/u013161278/article/details/115463531
需要去好好了解下Spring的异步机制了。