事件与监听
事件与监听是 niucloud 进行代码解耦的基础,是 niucloud 区别与其他系统一个很重要的技术点。通过事件与监听可以将系统的业务进行分离,比如支付,存储,订单业务等。下面针对具体的几个案例说明一下事件与监听的执行过程。后期可以与微服务设计中消息相结合
事件与监听架构
事件命名 event,监听命名 listener,包括系统定义的事件和插件定义的事件。具体文件夹如下: 

核心组件
事件基类 (Event)
继承自 Spring 的
ApplicationEvent包含站点 ID、应用列表、授权控制等核心属性
提供事件发布的基础结构
事件发布工具 (EventAndSubscribeOfPublisher)
提供多种事件发布方法
支持同步回调和异步发布
支持站点授权控制
事件定义器 (EventDefiner)
定义事件的数据结构
定义事件结果的数据结构
提供事件处理的抽象方法
事件监听器 (CallbackListener)
实现事件的具体处理逻辑
继承自事件定义器
提供回调结果
命名规范
事件定义:
业务名称+EventDefiner事件类:
业务名称+Event事件结果类:
业务名称+EventResult事件监听器:
业务名称+Listener
事件定义与发布
事件定义示例
事件定义采用 抽象类+内部静态事件类+内部静态结果类 的结构:
@EqualsAndHashCode(callSuper = false)
@Data
public abstract class MallShopGoodsListEventDefiner extends CallbackListener<MallShopGoodsListEventDefiner.MallShopGoodsListEvent> {
@Override
public abstract MallShopGoodsListEventResult handleCallback(MallShopGoodsListEvent event);
/**
* 事件结果定义
*/
@EqualsAndHashCode(callSuper = true)
@Data
public static class MallShopGoodsListEventResult extends EventResult {
//店铺街商品列表
private List<MallGoodsListVo> goods;
//首页-甄选好店商品列表
private List<MallGoodsListVo> goodsList;
}
/**
* 事件主题定义
*/
@EqualsAndHashCode(callSuper = true)
@Data
public static class MallShopGoodsListEvent extends Event {
private Integer num = 3; // 默认返回3个商品
}
}事件发布方式
使用 EventAndSubscribeOfPublisher 工具类发布事件:
// 1. 发布所有应用的事件(异步)
EventAndSubscribeOfPublisher.publishAll(event);
// 2. 根据站点ID发布事件(支持授权控制)
EventAndSubscribeOfPublisher.publishBySiteId(event);
// 3. 发布事件并获取回调结果(同步)
List<EventResult> results = EventAndSubscribeOfPublisher.publishAndCallback(event);
// 4. 根据站点ID发布事件并获取回调结果(同步)
List<EventResult> results = EventAndSubscribeOfPublisher.publishAndCallbackBySite(event);实际使用示例
在 SiteShopServiceImpl 中的使用:
// 发布店铺商品列表事件,获取商品数据
MallShopGoodsListEventDefiner.MallShopGoodsListEvent event = new MallShopGoodsListEventDefiner.MallShopGoodsListEvent();
event.setSiteId(site.getSiteId());
event.setNum(2); // 只返回2个商品
List<MallShopGoodsListEventDefiner.MallShopGoodsListEventResult> results = EventAndSubscribeOfPublisher.publishAndCallback(event);
// 处理回调结果
if (results != null && !results.isEmpty()) {
MallShopGoodsListEventDefiner.MallShopGoodsListEventResult result = results.get(0);
if (result != null && result.getGoodsList() != null) {
goodsList = result.getGoodsList();
}
}事件监听实现
监听器实现示例
监听器需要继承对应的事件定义器,并实现抽象的 handleCallback 方法:
@Component
public class MallShopGoodsListListener extends MallShopGoodsListEventDefiner {
@Override
public MallShopGoodsListEventResult handleCallback(MallShopGoodsListEvent event) {
MallShopGoodsListEventResult result = new MallShopGoodsListEventResult();
// 1. 获取参数
Integer siteId = event.getSiteId();
Integer num = event.getNum() != null ? event.getNum() : 3;
// 2. 执行业务逻辑
List<MallGoodsListVo> goodsList = new ArrayList<>();
// TODO: 查询店铺商品列表逻辑
// 3. 设置结果
result.setGoodsList(goodsList);
return result;
}
}同步与异步事件
异步事件
使用
publishAll或publishBySiteId方法适合不需要立即获取结果的场景,如会员注册后发送通知
执行效率高,不阻塞主线程
同步回调事件
使用
publishAndCallback或publishAndCallbackBySite方法适合需要获取扩展返回数据的场景,如支付方式扩展、营销价格计算
阻塞主线程,等待所有监听器处理完成
