前言
多个业务操作(发布课表、直播信息变更、讲义信息变更)需要执行一批相同逻辑处理(删除缓存),可以借助Spring自带的事件发布&订阅机制。 ps:懒得用 mq -_-
定义事件
@Getter
@Setter
public class CRChangeEvent extends ApplicationEvent {
/**
* 课表id集合
*/
private List<Integer> curriculumIds;
/**
* 是否发布课表
*/
private Boolean isCurriculumPublish;
public CRChangeEvent(Object source, List<Integer> curriculumIds) {
super(source);
this.curriculumIds = curriculumIds;
this.isCurriculumPublish = Boolean.FALSE;
}
public CRChangeEvent(Object source, Integer curriculumId) {
super(source);
this.curriculumIds = Collections.singletonList(curriculumId);
this.isCurriculumPublish = Boolean.FALSE;
}
public CRChangeEvent(Object source, Integer curriculumId, Boolean isCurriculumPublish) {
super(source);
this.curriculumIds = Collections.singletonList(curriculumId);
this.isCurriculumPublish = isCurriculumPublish;
}
}
定义监听器
/**
* 课表资源变更事件监听
*
*/
@Component
@Slf4j
public class CRChangeListener {
@Resource
private ArkRedisClient arkRedisClient;
/**
* 默认是同步的,添加 @Async 注解代表异步处理
* @param changeEvent 事件对象
*/
@EventListener
@Async
public void onProcessCRChange(CRChangeEvent changeEvent) {
log.info("课表资源变更监听开始清理缓存 changeEvent={}", JSON.toJSONString(changeEvent));
List<Integer> curriculumIds = changeEvent.getCurriculumIds();
if (CollectionUtils.isEmpty(curriculumIds)) {
log.info("课表资源变更事件监听,curriculumIds is null");
return;
}
curriculumIds.forEach(curriculumId -> {
arkRedisClient.del(RedisKeyEnum.CURRICULUM_LECTURE_NODE_LIST.getKey() + 1 + ":" + curriculumId);
});
}
}
发布事件
1. 启动类获取 AC
/**
* 在某些特殊的情况下,Bean需要实现某个功能,但该功能必须借助于Spring容器才能实现,此时就必须让该Bean先获取Spring容器,然后借助于Spring容器实现该功能。
* 为了让Bean获取它所在的Spring容器,可以让该Bean实现ApplicationContextAware接口。
* ApplicationContextAware 通过它Spring容器会自动把上下文环境对象调用ApplicationContextAware接口中的setApplicationContext方法。
* 在ApplicationContextAware的实现类中,就可以通过这个上下文环境对象得到Spring容器中的Bean。
* 看到*Aware就知道是干什么的了,就是属性注入的,
* 但是这个ApplicationContextAware的不同地方在于:实现了这个接口的bean,当spring容器初始化的时候,会自动的将ApplicationContext注入进来。
* Create By IntelliJ IDEA
*
*/
public class ProductServiceApplication implements ApplicationContextAware {
public static ApplicationContext AC;
public static void main(String[] args) {
System.setProperty("es.set.netty.runtime.available.processors", "false");
SpringApplication.run(ProductServiceApplication.class, args);
}
@Override
public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
AC = applicationContext;
}
}
2. 发布事件
import static com.iqihang.ark.product.ProductServiceApplication.AC;
...
AC.publishEvent(new CRChangeEvent(this, id, true));