Commit 2a349972b4768eab72c559ba9750008c3852ceee

Authored by YunaiV
1 parent 79a0b4cb

增加 Redis pub sub 机制

src/main/java/cn/iocoder/dashboard/framework/redis/config/RedisConfig.java
1 1 package cn.iocoder.dashboard.framework.redis.config;
2 2  
  3 +import cn.iocoder.dashboard.framework.redis.core.listener.AbstractMessageListener;
3 4 import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
  5 +import lombok.extern.slf4j.Slf4j;
4 6 import org.springframework.context.annotation.Bean;
5 7 import org.springframework.context.annotation.Configuration;
6 8 import org.springframework.data.redis.connection.RedisConnectionFactory;
7 9 import org.springframework.data.redis.core.RedisTemplate;
  10 +import org.springframework.data.redis.listener.ChannelTopic;
  11 +import org.springframework.data.redis.listener.RedisMessageListenerContainer;
8 12 import org.springframework.data.redis.serializer.RedisSerializer;
9 13  
  14 +import java.util.List;
  15 +
  16 +/**
  17 + * Redis 配置类
  18 + */
10 19 @Configuration
  20 +@Slf4j
11 21 public class RedisConfig {
12 22  
13 23 @Bean
... ... @@ -23,4 +33,20 @@ public class RedisConfig {
23 33 return template;
24 34 }
25 35  
  36 + @Bean
  37 + public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory factory,
  38 + List<AbstractMessageListener<?>> listeners) {
  39 + // 创建 RedisMessageListenerContainer 对象
  40 + RedisMessageListenerContainer container = new RedisMessageListenerContainer();
  41 + // 设置 RedisConnection 工厂。
  42 + container.setConnectionFactory(factory);
  43 + // 添加监听器
  44 + listeners.forEach(listener -> {
  45 + container.addMessageListener(listener, new ChannelTopic(listener.getChannel()));
  46 + log.info("[redisMessageListenerContainer][注册 Channel({}) 对应的监听器({})]",
  47 + listener.getChannel(), listener.getClass().getName());
  48 + });
  49 + return container;
  50 + }
  51 +
26 52 }
... ...
src/main/java/cn/iocoder/dashboard/framework/redis/core/RedisKeyDefine.java
... ... @@ -19,8 +19,6 @@ public class RedisKeyDefine {
19 19 HASH,
20 20 SET,
21 21 ZSET,
22   - STREAM,
23   - PUBSUB;
24 22  
25 23 }
26 24  
... ...
src/main/java/cn/iocoder/dashboard/framework/redis/core/listener/AbstractMessageListener.java 0 → 100644
  1 +package cn.iocoder.dashboard.framework.redis.core.listener;
  2 +
  3 +import org.springframework.data.redis.connection.MessageListener;
  4 +
  5 +/**
  6 + * Redis Pub/Sub 监听器抽象类,用于实现广播消费
  7 + *
  8 + * @author 芋道源码
  9 + */
  10 +public abstract class AbstractMessageListener<T> implements MessageListener {
  11 +
  12 + /**
  13 + * 获得 Sub 订阅的 Redis Channel 通道
  14 + *
  15 + * @return channel
  16 + */
  17 + public abstract String getChannel();
  18 +
  19 +}
... ...
src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/SysMenuRefreshConsumer.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.mq.consumer;
  2 +
  3 +import cn.iocoder.dashboard.framework.redis.core.listener.AbstractMessageListener;
  4 +import cn.iocoder.dashboard.modules.system.mq.message.permission.SysMenuRefreshMessage;
  5 +import org.springframework.data.redis.connection.Message;
  6 +import org.springframework.stereotype.Component;
  7 +
  8 +@Component
  9 +public class SysMenuRefreshConsumer extends AbstractMessageListener {
  10 +
  11 + @Override
  12 + public void onMessage(Message message, byte[] bytes) {
  13 + System.out.println(message);
  14 + }
  15 +
  16 + @Override
  17 + public String getChannel() {
  18 + return SysMenuRefreshMessage.TOPIC;
  19 + }
  20 +
  21 +}
... ...
src/main/java/cn/iocoder/dashboard/modules/system/mq/message/package-info.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.mq.message;
... ...
src/main/java/cn/iocoder/dashboard/modules/system/mq/message/permission/SysMenuRefreshMessage.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.mq.message.permission;
  2 +
  3 +import lombok.Data;
  4 +
  5 +/**
  6 + * 菜单数据刷新 Message
  7 + */
  8 +@Data
  9 +public class SysMenuRefreshMessage {
  10 +
  11 + public static final String TOPIC = "system.menu.refresh";
  12 +
  13 +}
... ...
src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/package-info.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.mq.producer;
... ...
src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/permission/SysMenuProducer.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.mq.producer.permission;
  2 +
  3 +import cn.iocoder.dashboard.modules.system.mq.message.permission.SysMenuRefreshMessage;
  4 +import org.springframework.data.redis.core.RedisTemplate;
  5 +import org.springframework.stereotype.Component;
  6 +
  7 +import javax.annotation.Resource;
  8 +
  9 +/**
  10 + * Menu 菜单相关消息的 Producer
  11 + */
  12 +@Component
  13 +public class SysMenuProducer {
  14 +
  15 + @Resource
  16 + private RedisTemplate<String, Object> redisTemplate;
  17 +
  18 + /**
  19 + * 发送 {@link SysMenuRefreshMessage} 消息
  20 + */
  21 + public void sendMenuRefreshMessage() {
  22 + SysMenuRefreshMessage message = new SysMenuRefreshMessage();
  23 + redisTemplate.convertAndSend(SysMenuRefreshMessage.TOPIC, message);
  24 + }
  25 +
  26 +}
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysMenuServiceImpl.java
... ... @@ -11,6 +11,7 @@ import cn.iocoder.dashboard.modules.system.dal.mysql.dao.permission.SysMenuMappe
11 11 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysMenuDO;
12 12 import cn.iocoder.dashboard.modules.system.enums.permission.MenuIdEnum;
13 13 import cn.iocoder.dashboard.modules.system.enums.permission.MenuTypeEnum;
  14 +import cn.iocoder.dashboard.modules.system.mq.producer.permission.SysMenuProducer;
14 15 import cn.iocoder.dashboard.modules.system.service.permission.SysMenuService;
15 16 import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
16 17 import cn.iocoder.dashboard.util.collection.CollectionUtils;
... ... @@ -68,6 +69,9 @@ public class SysMenuServiceImpl implements SysMenuService {
68 69 @Resource
69 70 private SysPermissionService permissionService;
70 71  
  72 + @Resource
  73 + private SysMenuProducer menuProducer;
  74 +
71 75 /**
72 76 * 初始化 {@link #menuCache} 和 {@link #permMenuCache} 缓存
73 77 */
... ... @@ -183,6 +187,8 @@ public class SysMenuServiceImpl implements SysMenuService {
183 187 SysMenuDO updateObject = SysMenuConvert.INSTANCE.convert(reqVO);
184 188 initMenuProperty(updateObject);
185 189 menuMapper.updateById(updateObject);
  190 + // 发送刷新消息
  191 + menuProducer.sendMenuRefreshMessage();
186 192 }
187 193  
188 194 /**
... ...