diff --git a/src/main/java/cn/iocoder/dashboard/framework/apollo/internals/DBConfigRepository.java b/src/main/java/cn/iocoder/dashboard/framework/apollo/internals/DBConfigRepository.java index 92431c620..910ec9f0d 100644 --- a/src/main/java/cn/iocoder/dashboard/framework/apollo/internals/DBConfigRepository.java +++ b/src/main/java/cn/iocoder/dashboard/framework/apollo/internals/DBConfigRepository.java @@ -28,6 +28,8 @@ public class DBConfigRepository extends AbstractConfigRepository { private final static ScheduledExecutorService m_executorService; + private static DBConfigRepository INSTANCE; + static { m_executorService = Executors.newScheduledThreadPool(1, ApolloThreadFactory.create(DBConfigRepository.class.getSimpleName(), true)); @@ -64,6 +66,19 @@ public class DBConfigRepository extends AbstractConfigRepository { this.trySync(); // 初始化定时任务 this.schedulePeriodicRefresh(); + + // 设置单例 + INSTANCE = this; + } + + /** + * 通知同步, + */ + public static void noticeSync() { + // 提交到线程池中,避免和 schedulePeriodicRefresh 并发问题 + m_executorService.submit(() -> { + INSTANCE.trySync(); + }); } @Override @@ -127,7 +142,6 @@ public class DBConfigRepository extends AbstractConfigRepository { Tracer.logEvent("Apollo.Client.Version", Apollo.VERSION); }, m_configUtil.getRefreshInterval(), m_configUtil.getRefreshInterval(), m_configUtil.getRefreshIntervalTimeUnit()); -// TimeUnit.SECONDS); } // ========== 数据库相关操作 ========== diff --git a/src/main/java/cn/iocoder/dashboard/framework/redis/core/RedisKeyDefine.java b/src/main/java/cn/iocoder/dashboard/framework/redis/core/RedisKeyDefine.java index a126f623a..ee3a342a0 100644 --- a/src/main/java/cn/iocoder/dashboard/framework/redis/core/RedisKeyDefine.java +++ b/src/main/java/cn/iocoder/dashboard/framework/redis/core/RedisKeyDefine.java @@ -19,6 +19,8 @@ public class RedisKeyDefine { HASH, SET, ZSET, + STREAM, + PUBSUB } diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/mq/consumer/config/InfConfigRefreshConsumer.java b/src/main/java/cn/iocoder/dashboard/modules/infra/mq/consumer/config/InfConfigRefreshConsumer.java new file mode 100644 index 000000000..064fb3182 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/mq/consumer/config/InfConfigRefreshConsumer.java @@ -0,0 +1,24 @@ +package cn.iocoder.dashboard.modules.infra.mq.consumer.config; + +import cn.iocoder.dashboard.framework.apollo.internals.DBConfigRepository; +import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener; +import cn.iocoder.dashboard.modules.infra.mq.message.config.InfConfigRefreshMessage; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 针对 {@link InfConfigRefreshMessage} 的消费者 + * + * @author 芋道源码 + */ +@Component +@Slf4j +public class InfConfigRefreshConsumer extends AbstractChannelMessageListener { + + @Override + public void onMessage(InfConfigRefreshMessage message) { + log.info("[onMessage][收到 Config 刷新消息]"); + DBConfigRepository.noticeSync(); + } + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/mq/consumer/package-info.java b/src/main/java/cn/iocoder/dashboard/modules/infra/mq/consumer/package-info.java new file mode 100644 index 000000000..301ea9ad5 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/mq/consumer/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.dashboard.modules.infra.mq.consumer; diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/mq/message/config/InfConfigRefreshMessage.java b/src/main/java/cn/iocoder/dashboard/modules/infra/mq/message/config/InfConfigRefreshMessage.java new file mode 100644 index 000000000..9250f33f8 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/mq/message/config/InfConfigRefreshMessage.java @@ -0,0 +1,17 @@ +package cn.iocoder.dashboard.modules.infra.mq.message.config; + +import cn.iocoder.dashboard.framework.redis.core.pubsub.ChannelMessage; +import lombok.Data; + +/** + * 配置数据刷新 Message + */ +@Data +public class InfConfigRefreshMessage implements ChannelMessage { + + @Override + public String getChannel() { + return "infra.config.refresh"; + } + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/mq/message/package-info.java b/src/main/java/cn/iocoder/dashboard/modules/infra/mq/message/package-info.java new file mode 100644 index 000000000..5c63e494c --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/mq/message/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.dashboard.modules.infra.mq.message; diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/mq/producer/config/InfConfigProducer.java b/src/main/java/cn/iocoder/dashboard/modules/infra/mq/producer/config/InfConfigProducer.java new file mode 100644 index 000000000..1cb240db6 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/mq/producer/config/InfConfigProducer.java @@ -0,0 +1,27 @@ +package cn.iocoder.dashboard.modules.infra.mq.producer.config; + +import cn.iocoder.dashboard.framework.redis.core.util.RedisMessageUtils; +import cn.iocoder.dashboard.modules.infra.mq.message.config.InfConfigRefreshMessage; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * Config 配置相关消息的 Producer + */ +@Component +public class InfConfigProducer { + + @Resource + private StringRedisTemplate stringRedisTemplate; + + /** + * 发送 {@link InfConfigRefreshMessage} 消息 + */ + public void sendConfigRefreshMessage() { + InfConfigRefreshMessage message = new InfConfigRefreshMessage(); + RedisMessageUtils.sendChannelMessage(stringRedisTemplate, message); + } + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/mq/producer/package-info.java b/src/main/java/cn/iocoder/dashboard/modules/infra/mq/producer/package-info.java new file mode 100644 index 000000000..0895cd99a --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/mq/producer/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.dashboard.modules.infra.mq.producer; diff --git a/src/main/java/cn/iocoder/dashboard/modules/infra/service/config/impl/InfConfigServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/infra/service/config/impl/InfConfigServiceImpl.java index 1e2ff841c..6134751d9 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/infra/service/config/impl/InfConfigServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/infra/service/config/impl/InfConfigServiceImpl.java @@ -10,6 +10,7 @@ import cn.iocoder.dashboard.modules.infra.convert.config.InfConfigConvert; import cn.iocoder.dashboard.modules.infra.dal.mysql.dao.config.InfConfigMapper; import cn.iocoder.dashboard.modules.infra.dal.mysql.dataobject.config.InfConfigDO; import cn.iocoder.dashboard.modules.infra.enums.config.InfConfigTypeEnum; +import cn.iocoder.dashboard.modules.infra.mq.producer.config.InfConfigProducer; import cn.iocoder.dashboard.modules.infra.service.config.InfConfigService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -30,6 +31,9 @@ public class InfConfigServiceImpl implements InfConfigService { @Resource private InfConfigMapper configMapper; + @Resource + private InfConfigProducer configProducer; + @Override public PageResult getConfigPage(InfConfigPageReqVO reqVO) { return configMapper.selectPage(reqVO); @@ -58,6 +62,8 @@ public class InfConfigServiceImpl implements InfConfigService { InfConfigDO config = InfConfigConvert.INSTANCE.convert(reqVO); config.setType(InfConfigTypeEnum.CUSTOM.getType()); configMapper.insert(config); + // 发送刷新消息 + configProducer.sendConfigRefreshMessage(); return config.getId(); } @@ -68,6 +74,8 @@ public class InfConfigServiceImpl implements InfConfigService { // 更新参数配置 InfConfigDO updateObj = InfConfigConvert.INSTANCE.convert(reqVO); configMapper.updateById(updateObj); + // 发送刷新消息 + configProducer.sendConfigRefreshMessage(); } @Override @@ -80,6 +88,8 @@ public class InfConfigServiceImpl implements InfConfigService { } // 删除 configMapper.deleteById(id); + // 发送刷新消息 + configProducer.sendConfigRefreshMessage(); } private void checkCreateOrUpdate(Long id, String key) { @@ -113,4 +123,5 @@ public class InfConfigServiceImpl implements InfConfigService { throw ServiceExceptionUtil.exception(CONFIG_NAME_DUPLICATE); } } + } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/dept/SysDeptProducer.java b/src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/dept/SysDeptProducer.java index 707eeb018..4ad7db4b8 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/dept/SysDeptProducer.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/dept/SysDeptProducer.java @@ -19,7 +19,7 @@ public class SysDeptProducer { /** * 发送 {@link SysDeptRefreshMessage} 消息 */ - public void sendMenuRefreshMessage() { + public void sendDeptRefreshMessage() { SysDeptRefreshMessage message = new SysDeptRefreshMessage(); RedisMessageUtils.sendChannelMessage(stringRedisTemplate, message); } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/dict/SysDictDataProducer.java b/src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/dict/SysDictDataProducer.java index 603db6bdf..2ccfc51d2 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/dict/SysDictDataProducer.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/dict/SysDictDataProducer.java @@ -19,7 +19,7 @@ public class SysDictDataProducer { /** * 发送 {@link SysDictDataRefreshMessage} 消息 */ - public void sendMenuRefreshMessage() { + public void sendDictDataRefreshMessage() { SysDictDataRefreshMessage message = new SysDictDataRefreshMessage(); RedisMessageUtils.sendChannelMessage(stringRedisTemplate, message); } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/impl/SysDeptServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/impl/SysDeptServiceImpl.java index e20c68d3e..db41e7111 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/impl/SysDeptServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/impl/SysDeptServiceImpl.java @@ -174,8 +174,8 @@ public class SysDeptServiceImpl implements SysDeptService { // 插入部门 SysDeptDO dept = SysDeptConvert.INSTANCE.convert(reqVO); deptMapper.insert(dept); - // 发送消息 - deptProducer.sendMenuRefreshMessage(); + // 发送刷新消息 + deptProducer.sendDeptRefreshMessage(); return dept.getId(); } @@ -186,8 +186,8 @@ public class SysDeptServiceImpl implements SysDeptService { // 更新部门 SysDeptDO updateObj = SysDeptConvert.INSTANCE.convert(reqVO); deptMapper.updateById(updateObj); - // 发送消息 - deptProducer.sendMenuRefreshMessage(); + // 发送刷新消息 + deptProducer.sendDeptRefreshMessage(); } @Override @@ -200,8 +200,10 @@ public class SysDeptServiceImpl implements SysDeptService { } // 删除部门 deptMapper.deleteById(id); - // 发送消息 - deptProducer.sendMenuRefreshMessage(); + // TODO 需要处理下与角色的数据权限关联,等做数据权限一起处理下 + + // 发送刷新消息 + deptProducer.sendDeptRefreshMessage(); } private void checkCreateOrUpdate(Long id, Long parentId, String name) { diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java index 7f5517c48..e33360fe7 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java @@ -160,8 +160,8 @@ public class SysDictDataServiceImpl implements SysDictDataService { // 插入字典类型 SysDictDataDO dictData = SysDictDataConvert.INSTANCE.convert(reqVO); dictDataMapper.insert(dictData); - // 发送消息 - dictDataProducer.sendMenuRefreshMessage(); + // 发送刷新消息 + dictDataProducer.sendDictDataRefreshMessage(); return dictData.getId(); } @@ -172,8 +172,8 @@ public class SysDictDataServiceImpl implements SysDictDataService { // 更新字典类型 SysDictDataDO updateObj = SysDictDataConvert.INSTANCE.convert(reqVO); dictDataMapper.updateById(updateObj); - // 发送消息 - dictDataProducer.sendMenuRefreshMessage(); + // 发送刷新消息 + dictDataProducer.sendDictDataRefreshMessage(); } @Override @@ -182,8 +182,8 @@ public class SysDictDataServiceImpl implements SysDictDataService { this.checkDictDataExists(id); // 删除字典数据 dictDataMapper.deleteById(id); - // 发送消息 - dictDataProducer.sendMenuRefreshMessage(); + // 发送刷新消息 + dictDataProducer.sendDictDataRefreshMessage(); } @Override diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysMenuServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysMenuServiceImpl.java index 6edab915b..cb8dbadf0 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysMenuServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysMenuServiceImpl.java @@ -219,7 +219,7 @@ public class SysMenuServiceImpl implements SysMenuService { menuMapper.deleteById(menuId); // 删除授予给角色的权限 permissionService.processMenuDeleted(menuId); - // 发送刷新消息. 注意,需要事务提交后,在进行发送消息。不然 db 还未提交,结果缓存先刷新了 + // 发送刷新消息. 注意,需要事务提交后,在进行发送刷新消息。不然 db 还未提交,结果缓存先刷新了 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { @Override