瀏覽代碼

增加 Redis pub sub 机制

YunaiV 4 年之前
父節點
當前提交
2a349972b4

+ 26 - 0
src/main/java/cn/iocoder/dashboard/framework/redis/config/RedisConfig.java

@@ -1,13 +1,23 @@
 package cn.iocoder.dashboard.framework.redis.config;
 
+import cn.iocoder.dashboard.framework.redis.core.listener.AbstractMessageListener;
 import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.data.redis.connection.RedisConnectionFactory;
 import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.listener.ChannelTopic;
+import org.springframework.data.redis.listener.RedisMessageListenerContainer;
 import org.springframework.data.redis.serializer.RedisSerializer;
 
+import java.util.List;
+
+/**
+ * Redis 配置类
+ */
 @Configuration
+@Slf4j
 public class RedisConfig {
 
     @Bean
@@ -23,4 +33,20 @@ public class RedisConfig {
         return template;
     }
 
+    @Bean
+    public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory factory,
+                                                                       List<AbstractMessageListener<?>> listeners) {
+        // 创建 RedisMessageListenerContainer 对象
+        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
+        // 设置 RedisConnection 工厂。
+        container.setConnectionFactory(factory);
+        // 添加监听器
+        listeners.forEach(listener -> {
+            container.addMessageListener(listener, new ChannelTopic(listener.getChannel()));
+            log.info("[redisMessageListenerContainer][注册 Channel({}) 对应的监听器({})]",
+                    listener.getChannel(), listener.getClass().getName());
+        });
+        return container;
+    }
+
 }

+ 0 - 2
src/main/java/cn/iocoder/dashboard/framework/redis/core/RedisKeyDefine.java

@@ -19,8 +19,6 @@ public class RedisKeyDefine {
         HASH,
         SET,
         ZSET,
-        STREAM,
-        PUBSUB;
 
     }
 

+ 19 - 0
src/main/java/cn/iocoder/dashboard/framework/redis/core/listener/AbstractMessageListener.java

@@ -0,0 +1,19 @@
+package cn.iocoder.dashboard.framework.redis.core.listener;
+
+import org.springframework.data.redis.connection.MessageListener;
+
+/**
+ * Redis Pub/Sub 监听器抽象类,用于实现广播消费
+ *
+ * @author 芋道源码
+ */
+public abstract class AbstractMessageListener<T> implements MessageListener {
+
+    /**
+     * 获得 Sub 订阅的 Redis Channel 通道
+     *
+     * @return channel
+     */
+    public abstract String getChannel();
+
+}

+ 21 - 0
src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/SysMenuRefreshConsumer.java

@@ -0,0 +1,21 @@
+package cn.iocoder.dashboard.modules.system.mq.consumer;
+
+import cn.iocoder.dashboard.framework.redis.core.listener.AbstractMessageListener;
+import cn.iocoder.dashboard.modules.system.mq.message.permission.SysMenuRefreshMessage;
+import org.springframework.data.redis.connection.Message;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SysMenuRefreshConsumer extends AbstractMessageListener {
+
+    @Override
+    public void onMessage(Message message, byte[] bytes) {
+        System.out.println(message);
+    }
+
+    @Override
+    public String getChannel() {
+        return SysMenuRefreshMessage.TOPIC;
+    }
+
+}

+ 1 - 0
src/main/java/cn/iocoder/dashboard/modules/system/mq/message/package-info.java

@@ -0,0 +1 @@
+package cn.iocoder.dashboard.modules.system.mq.message;

+ 13 - 0
src/main/java/cn/iocoder/dashboard/modules/system/mq/message/permission/SysMenuRefreshMessage.java

@@ -0,0 +1,13 @@
+package cn.iocoder.dashboard.modules.system.mq.message.permission;
+
+import lombok.Data;
+
+/**
+ * 菜单数据刷新 Message
+ */
+@Data
+public class SysMenuRefreshMessage {
+
+    public static final String TOPIC = "system.menu.refresh";
+
+}

+ 1 - 0
src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/package-info.java

@@ -0,0 +1 @@
+package cn.iocoder.dashboard.modules.system.mq.producer;

+ 26 - 0
src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/permission/SysMenuProducer.java

@@ -0,0 +1,26 @@
+package cn.iocoder.dashboard.modules.system.mq.producer.permission;
+
+import cn.iocoder.dashboard.modules.system.mq.message.permission.SysMenuRefreshMessage;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * Menu 菜单相关消息的 Producer
+ */
+@Component
+public class SysMenuProducer {
+
+    @Resource
+    private RedisTemplate<String, Object> redisTemplate;
+
+    /**
+     * 发送 {@link SysMenuRefreshMessage} 消息
+     */
+    public void sendMenuRefreshMessage() {
+        SysMenuRefreshMessage message = new SysMenuRefreshMessage();
+        redisTemplate.convertAndSend(SysMenuRefreshMessage.TOPIC, message);
+    }
+
+}

+ 6 - 0
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
 import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysMenuDO;
 import cn.iocoder.dashboard.modules.system.enums.permission.MenuIdEnum;
 import cn.iocoder.dashboard.modules.system.enums.permission.MenuTypeEnum;
+import cn.iocoder.dashboard.modules.system.mq.producer.permission.SysMenuProducer;
 import cn.iocoder.dashboard.modules.system.service.permission.SysMenuService;
 import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
 import cn.iocoder.dashboard.util.collection.CollectionUtils;
@@ -68,6 +69,9 @@ public class SysMenuServiceImpl implements SysMenuService {
     @Resource
     private SysPermissionService permissionService;
 
+    @Resource
+    private SysMenuProducer menuProducer;
+
     /**
      * 初始化 {@link #menuCache} 和 {@link #permMenuCache} 缓存
      */
@@ -183,6 +187,8 @@ public class SysMenuServiceImpl implements SysMenuService {
         SysMenuDO updateObject = SysMenuConvert.INSTANCE.convert(reqVO);
         initMenuProperty(updateObject);
         menuMapper.updateById(updateObject);
+        // 发送刷新消息
+        menuProducer.sendMenuRefreshMessage();
     }
 
     /**