mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-28 16:58:43 +08:00 
			
		
		
		
	【移除】Apollo 配置中心,简化学习成本
This commit is contained in:
		| @@ -28,7 +28,6 @@ | ||||
|         <dynamic-datasource.version>3.5.2</dynamic-datasource.version> | ||||
|         <redisson.version>3.17.7</redisson.version> | ||||
|         <!-- Config 配置中心相关 --> | ||||
|         <apollo.version>2.0.1</apollo.version> | ||||
|         <!-- 服务保障相关 --> | ||||
|         <lock4j.version>2.2.2</lock4j.version> | ||||
|         <resilience4j.version>1.7.1</resilience4j.version> | ||||
| @@ -224,17 +223,6 @@ | ||||
|             </dependency> | ||||
|  | ||||
|             <!-- Config 配置中心相关 --> | ||||
|             <dependency> | ||||
|                 <groupId>cn.iocoder.boot</groupId> | ||||
|                 <artifactId>yudao-spring-boot-starter-config</artifactId> | ||||
|                 <version>${revision}</version> | ||||
|             </dependency> | ||||
|  | ||||
|             <dependency> | ||||
|                 <groupId>com.ctrip.framework.apollo</groupId> | ||||
|                 <artifactId>apollo-client</artifactId> <!-- 引入 Apollo Client 库,实现内嵌的配置中心 --> | ||||
|                 <version>${apollo.version}</version> | ||||
|             </dependency> | ||||
|  | ||||
|             <!-- Job 定时任务相关 --> | ||||
|             <dependency> | ||||
|   | ||||
| @@ -20,7 +20,6 @@ | ||||
|         <module>yudao-spring-boot-starter-file</module> | ||||
|         <module>yudao-spring-boot-starter-monitor</module> | ||||
|         <module>yudao-spring-boot-starter-protection</module> | ||||
|         <module>yudao-spring-boot-starter-config</module> | ||||
|         <module>yudao-spring-boot-starter-job</module> | ||||
|         <module>yudao-spring-boot-starter-mq</module> | ||||
|  | ||||
|   | ||||
| @@ -1,37 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||||
|          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|     <parent> | ||||
|         <groupId>cn.iocoder.boot</groupId> | ||||
|         <artifactId>yudao-framework</artifactId> | ||||
|         <version>${revision}</version> | ||||
|     </parent> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <artifactId>yudao-spring-boot-starter-config</artifactId> | ||||
|     <packaging>jar</packaging> | ||||
|  | ||||
|     <name>${project.artifactId}</name> | ||||
|     <description>配置中心,基于 Apollo 魔改实现</description> | ||||
|     <url>https://github.com/YunaiV/ruoyi-vue-pro</url> | ||||
|  | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>cn.iocoder.boot</groupId> | ||||
|             <artifactId>yudao-common</artifactId> | ||||
|         </dependency> | ||||
|  | ||||
|         <!-- Spring 核心 --> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter</artifactId> | ||||
|         </dependency> | ||||
|  | ||||
|         <!-- Config 配置中心相关 --> | ||||
|         <dependency> | ||||
|             <groupId>com.ctrip.framework.apollo</groupId> | ||||
|             <artifactId>apollo-client</artifactId> <!-- 引入 Apollo Client 库,实现内嵌的配置中心 --> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
|  | ||||
| </project> | ||||
| @@ -1,22 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.apollo.core; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.apollo.internals.ConfigFrameworkDAO; | ||||
|  | ||||
| /** | ||||
|  * 针对 {@link com.ctrip.framework.apollo.core.ConfigConsts} 的补充,主要增加: | ||||
|  * | ||||
|  * 1. apollo.jdbc.* 配置项的枚举 | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| public class ConfigConsts { | ||||
|  | ||||
|     /** | ||||
|      * {@link ConfigFrameworkDAO} 的实现类 | ||||
|      */ | ||||
|     public static final String APOLLO_JDBC_DAO = "apollo.jdbc.dao"; | ||||
|     public static final String APOLLO_JDBC_URL = "apollo.jdbc.url"; | ||||
|     public static final String APOLLO_JDBC_USERNAME = "apollo.jdbc.username"; | ||||
|     public static final String APOLLO_JDBC_PASSWORD = "apollo.jdbc.password"; | ||||
|  | ||||
| } | ||||
| @@ -1,32 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.apollo.internals; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.apollo.internals.dto.ConfigRespDTO; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 配置 Framework DAO 接口 | ||||
|  * | ||||
|  * 注意,实现类必须提供 (String jdbcUrl, String username, String password) 构造方法 | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| public interface ConfigFrameworkDAO { | ||||
|  | ||||
|     /** | ||||
|      * 查询是否存在比 maxUpdateTime 的更新记录数量 | ||||
|      * | ||||
|      * @param maxUpdateTime 最大更新时间 | ||||
|      * @return 是否存在 | ||||
|      */ | ||||
|     int selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime); | ||||
|  | ||||
|     /** | ||||
|      * 查询配置列表 | ||||
|      * | ||||
|      * @return 配置列表 | ||||
|      */ | ||||
|     List<ConfigRespDTO> selectList(); | ||||
|  | ||||
| } | ||||
| @@ -1,183 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.apollo.internals; | ||||
|  | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.hutool.core.util.ClassUtil; | ||||
| import cn.hutool.core.util.ReflectUtil; | ||||
| import cn.iocoder.yudao.framework.apollo.core.ConfigConsts; | ||||
| import cn.iocoder.yudao.framework.apollo.internals.dto.ConfigRespDTO; | ||||
| import com.ctrip.framework.apollo.Apollo; | ||||
| import com.ctrip.framework.apollo.build.ApolloInjector; | ||||
| import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory; | ||||
| import com.ctrip.framework.apollo.enums.ConfigSourceType; | ||||
| import com.ctrip.framework.apollo.internals.AbstractConfigRepository; | ||||
| import com.ctrip.framework.apollo.internals.ConfigRepository; | ||||
| import com.ctrip.framework.apollo.tracer.Tracer; | ||||
| import com.ctrip.framework.apollo.util.ConfigUtil; | ||||
| import com.ctrip.framework.apollo.util.factory.PropertiesFactory; | ||||
| import lombok.SneakyThrows; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
|  | ||||
| import java.lang.reflect.Constructor; | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.Comparator; | ||||
| import java.util.List; | ||||
| import java.util.Properties; | ||||
| import java.util.concurrent.Executors; | ||||
| import java.util.concurrent.ScheduledExecutorService; | ||||
|  | ||||
| @Slf4j | ||||
| 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)); | ||||
|     } | ||||
|  | ||||
|     private final ConfigUtil m_configUtil; | ||||
|     private final PropertiesFactory propertiesFactory; | ||||
|     private final String m_namespace; | ||||
|  | ||||
|     /** | ||||
|      * 配置缓存,使用 Properties 存储 | ||||
|      */ | ||||
|     private volatile Properties m_configCache; | ||||
|     /** | ||||
|      * 缓存配置的最大更新时间,用于后续的增量轮询,判断是否有更新 | ||||
|      */ | ||||
|     private volatile LocalDateTime maxUpdateTime; | ||||
|  | ||||
|     /** | ||||
|      * 配置读取 DAO | ||||
|      */ | ||||
|     private final ConfigFrameworkDAO configFrameworkDAO; | ||||
|  | ||||
|     public DBConfigRepository(String namespace) { | ||||
|         // 初始化变量 | ||||
|         this.m_namespace = namespace; | ||||
|         this.propertiesFactory = ApolloInjector.getInstance(PropertiesFactory.class); | ||||
|         this.m_configUtil = ApolloInjector.getInstance(ConfigUtil.class); | ||||
|         // 初始化 DB | ||||
|         this.configFrameworkDAO = createConfigFrameworkDAO(); | ||||
|  | ||||
|         // 初始化加载 | ||||
|         this.trySync(); | ||||
|         // 初始化定时任务 | ||||
|         this.schedulePeriodicRefresh(); | ||||
|  | ||||
|         // 设置单例 | ||||
|         INSTANCE = this; | ||||
|     } | ||||
|  | ||||
|     @SneakyThrows | ||||
|     private static ConfigFrameworkDAO createConfigFrameworkDAO() { | ||||
|         String dao = System.getProperty(ConfigConsts.APOLLO_JDBC_DAO); | ||||
|         String url = System.getProperty(ConfigConsts.APOLLO_JDBC_URL); | ||||
|         String username = System.getProperty(ConfigConsts.APOLLO_JDBC_USERNAME); | ||||
|         String password = System.getProperty(ConfigConsts.APOLLO_JDBC_PASSWORD); | ||||
|         // 创建 DBConfigRepository 对象 | ||||
|         Class<? extends ConfigFrameworkDAO> clazz = ClassUtil.loadClass(dao); | ||||
|         Constructor<? extends ConfigFrameworkDAO> constructor = ReflectUtil.getConstructor(clazz, String.class, String.class, String.class); | ||||
|         return constructor.newInstance(url, username, password); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 通知同步, | ||||
|      */ | ||||
|     public static void noticeSync() { | ||||
|         // 提交到线程池中,避免和 schedulePeriodicRefresh 并发问题 | ||||
|         m_executorService.submit(() -> { | ||||
|             INSTANCE.trySync(); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void sync() { | ||||
|         // 第一步,尝试获取配置 | ||||
|         List<ConfigRespDTO> configs = this.loadConfigIfUpdate(this.maxUpdateTime); | ||||
|         if (CollUtil.isEmpty(configs)) { // 如果没有更新,则返回 | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // 第二步,构建新的 Properties | ||||
|         Properties newProperties = this.buildProperties(configs); | ||||
|         this.m_configCache = newProperties; | ||||
|         // 第三步,获取最大的配置时间 | ||||
|         assert configs.size() > 0; // 断言,避免告警 | ||||
|         this.maxUpdateTime = configs.stream().max(Comparator.comparing(ConfigRespDTO::getUpdateTime)).get().getUpdateTime(); | ||||
|         // 第四部,触发配置刷新!重要!!!! | ||||
|         super.fireRepositoryChange(m_namespace, newProperties); | ||||
|         log.info("[sync][缓存配置,数量为:{}]", configs.size()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Properties getConfig() { | ||||
|         // 兜底,避免可能存在配置为 null 的情况 | ||||
|         if (m_configCache == null) { | ||||
|             this.trySync(); | ||||
|         } | ||||
|         // 返回配置 | ||||
|         return m_configCache; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void setUpstreamRepository(ConfigRepository upstreamConfigRepository) { | ||||
|         // 啥事不做 | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public ConfigSourceType getSourceType() { | ||||
|         return ConfigSourceType.REMOTE; | ||||
|     } | ||||
|  | ||||
|     private Properties buildProperties(List<ConfigRespDTO> configs) { | ||||
|         Properties properties = propertiesFactory.getPropertiesInstance(); | ||||
|         configs.stream().filter(config -> !config.getDeleted()) // 过滤掉被删除的配置 | ||||
|                 .forEach(config -> properties.put(config.getKey(), config.getValue())); | ||||
|         return properties; | ||||
|     } | ||||
|  | ||||
|     // ========== 定时器相关操作 ========== | ||||
|  | ||||
|     private void schedulePeriodicRefresh() { | ||||
|         log.debug("Schedule periodic refresh with interval: {} {}", | ||||
|                 m_configUtil.getRefreshInterval(), m_configUtil.getRefreshIntervalTimeUnit()); | ||||
|         m_executorService.scheduleAtFixedRate(() -> { | ||||
|             Tracer.logEvent("Apollo.ConfigService", String.format("periodicRefresh: %s", m_namespace)); | ||||
|             log.debug("refresh config for namespace: {}", m_namespace); | ||||
|  | ||||
|             // 执行同步. 内部已经 try catch 掉异常,无需在处理 | ||||
|             trySync(); | ||||
|  | ||||
|             Tracer.logEvent("Apollo.Client.Version", Apollo.VERSION); | ||||
|         }, m_configUtil.getRefreshInterval(), m_configUtil.getRefreshInterval(), | ||||
|                 m_configUtil.getRefreshIntervalTimeUnit()); | ||||
|     } | ||||
|  | ||||
|     // ========== 数据库相关操作 ========== | ||||
|  | ||||
|     /** | ||||
|      * 如果配置发生变化,从数据库中获取最新的全量配置。 | ||||
|      * 如果未发生变化,则返回空 | ||||
|      * | ||||
|      * @param maxUpdateTime 当前配置的最大更新时间 | ||||
|      * @return 配置列表 | ||||
|      */ | ||||
|     private List<ConfigRespDTO> loadConfigIfUpdate(LocalDateTime maxUpdateTime) { | ||||
|         // 第一步,判断是否要更新。 | ||||
|         if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据 | ||||
|             log.info("[loadConfigIfUpdate][首次加载全量配置]"); | ||||
|         } else { // 判断数据库中是否有更新的配置 | ||||
|             if (configFrameworkDAO.selectCountByUpdateTimeGt(maxUpdateTime) == 0) { | ||||
|                 return null; | ||||
|             } | ||||
|             log.info("[loadConfigIfUpdate][增量加载全量配置]"); | ||||
|         } | ||||
|         // 第二步,如果有更新,则从数据库加载所有配置 | ||||
|         return configFrameworkDAO.selectList(); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,75 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.apollo.internals; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.apollo.spi.DBConfigFactory; | ||||
| import com.ctrip.framework.apollo.exceptions.ApolloConfigException; | ||||
| import com.ctrip.framework.apollo.internals.*; | ||||
| import com.ctrip.framework.apollo.spi.*; | ||||
| import com.ctrip.framework.apollo.tracer.Tracer; | ||||
| import com.ctrip.framework.apollo.util.ConfigUtil; | ||||
| import com.ctrip.framework.apollo.util.factory.DefaultPropertiesFactory; | ||||
| import com.ctrip.framework.apollo.util.factory.PropertiesFactory; | ||||
| import com.ctrip.framework.apollo.util.http.DefaultHttpClient; | ||||
| import com.ctrip.framework.apollo.util.yaml.YamlParser; | ||||
| import com.google.inject.AbstractModule; | ||||
| import com.google.inject.Guice; | ||||
| import com.google.inject.Singleton; | ||||
|  | ||||
| /** | ||||
|  * Guice injector | ||||
|  * | ||||
|  * 基于 Guice 注入器实现类 | ||||
|  * | ||||
|  * @author Jason Song(song_s@ctrip.com) | ||||
|  */ | ||||
| public class DefaultXInjector implements Injector { | ||||
|  | ||||
|     private final com.google.inject.Injector m_injector; | ||||
|  | ||||
|     public DefaultXInjector() { | ||||
|         try { | ||||
|             m_injector = Guice.createInjector(new ApolloModule()); | ||||
|         } catch (Throwable ex) { | ||||
|             ApolloConfigException exception = new ApolloConfigException("Unable to initialize Guice Injector!", ex); | ||||
|             Tracer.logError(exception); | ||||
|             throw exception; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public <T> T getInstance(Class<T> clazz) { | ||||
|         try { | ||||
|             return m_injector.getInstance(clazz); | ||||
|         } catch (Throwable ex) { | ||||
|             Tracer.logError(ex); | ||||
|             throw new ApolloConfigException(String.format("Unable to load instance for %s!", clazz.getName()), ex); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public <T> T getInstance(Class<T> clazz, String name) { | ||||
|         // Guice does not support get instance by type and name | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     private static class ApolloModule extends AbstractModule { | ||||
|  | ||||
|         @Override | ||||
|         protected void configure() { | ||||
|             bind(ConfigManager.class).to(DefaultConfigManager.class).in(Singleton.class); | ||||
|             bind(ConfigFactoryManager.class).to(DefaultConfigFactoryManager.class).in(Singleton.class); | ||||
|             bind(ConfigRegistry.class).to(DefaultConfigRegistry.class).in(Singleton.class); | ||||
|  | ||||
|             // 自定义 ConfigFactory 实现,使用 DB 作为数据源 | ||||
|             bind(ConfigFactory.class).to(DBConfigFactory.class).in(Singleton.class); | ||||
|  | ||||
|             bind(ConfigUtil.class).in(Singleton.class); | ||||
|             bind(DefaultHttpClient.class).in(Singleton.class); | ||||
|             bind(ConfigServiceLocator.class).in(Singleton.class); | ||||
|             bind(RemoteConfigLongPollService.class).in(Singleton.class); | ||||
|             bind(YamlParser.class).in(Singleton.class); | ||||
|             bind(PropertiesFactory.class).to(DefaultPropertiesFactory.class).in(Singleton.class); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,33 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.apollo.internals.dto; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
|  | ||||
| /** | ||||
|  * 配置 Response DTO | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| @Data | ||||
| public class ConfigRespDTO { | ||||
|  | ||||
|     /** | ||||
|      * 参数键名 | ||||
|      */ | ||||
|     private String key; | ||||
|     /** | ||||
|      * 参数键值 | ||||
|      */ | ||||
|     private String value; | ||||
|  | ||||
|     /** | ||||
|      * 是否删除 | ||||
|      */ | ||||
|     private Boolean deleted; | ||||
|     /** | ||||
|      * 更新时间 | ||||
|      */ | ||||
|     private LocalDateTime updateTime; | ||||
|  | ||||
| } | ||||
| @@ -1,13 +0,0 @@ | ||||
| /** | ||||
|  * 配置中心客户端,基于 Apollo Client 进行简化 | ||||
|  * | ||||
|  * 差别在于,我们使用 cn.iocoder.yudao.modules.infra.dal.dataobject.config.InfConfigDO 表作为配置源。 | ||||
|  * 当然,功能肯定也会相对少些,满足最小化诉求。 | ||||
|  * | ||||
|  * 1. 项目初始化时,可以使用 SysConfigDO 表的配置 | ||||
|  * 2. 使用 Spring @Value 可以注入属性 | ||||
|  * 3. SysConfigDO 表的配置修改时,注入到 @Value 的属性可以刷新 | ||||
|  * | ||||
|  * 另外,整个包结构会参考 Apollo 为主,方便维护与理解 | ||||
|  */ | ||||
| package cn.iocoder.yudao.framework.apollo; | ||||
| @@ -1,32 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.apollo.spi; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.apollo.internals.DBConfigRepository; | ||||
| import com.ctrip.framework.apollo.Config; | ||||
| import com.ctrip.framework.apollo.ConfigFile; | ||||
| import com.ctrip.framework.apollo.core.enums.ConfigFileFormat; | ||||
| import com.ctrip.framework.apollo.internals.ConfigRepository; | ||||
| import com.ctrip.framework.apollo.internals.DefaultConfig; | ||||
| import com.ctrip.framework.apollo.spi.ConfigFactory; | ||||
|  | ||||
| /** | ||||
|  * 基于 DB 的 ConfigFactory 实现类 | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| public class DBConfigFactory implements ConfigFactory { | ||||
|  | ||||
|     @Override | ||||
|     public Config create(String namespace) { | ||||
|         return new DefaultConfig(namespace, this.createDBConfigRepository(namespace)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public ConfigFile createConfigFile(String namespace, ConfigFileFormat configFileFormat) { | ||||
|         throw new UnsupportedOperationException("暂不支持 Apollo 配置文件"); | ||||
|     } | ||||
|  | ||||
|     private ConfigRepository createDBConfigRepository(String namespace) { | ||||
|         return new DBConfigRepository(namespace); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,63 +0,0 @@ | ||||
| package cn.iocoder.yudao.framework.apollo.spring.boot; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.apollo.core.ConfigConsts; | ||||
| import com.google.common.base.Strings; | ||||
| import org.springframework.boot.SpringApplication; | ||||
| import org.springframework.boot.env.EnvironmentPostProcessor; | ||||
| import org.springframework.core.Ordered; | ||||
| import org.springframework.core.env.ConfigurableEnvironment; | ||||
|  | ||||
| /** | ||||
|  * 对 {@link com.ctrip.framework.apollo.spring.boot.ApolloApplicationContextInitializer} 的补充,目前的目的有: | ||||
|  * | ||||
|  * 1. 将自定义的 apollo.jdbc 设置到 System 变量中 | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| public class ApolloApplicationContextInitializer implements EnvironmentPostProcessor, Ordered { | ||||
|  | ||||
|     /** | ||||
|      * 优先级更高,要早于 Apollo 的 ApolloApplicationContextInitializer 的初始化 | ||||
|      */ | ||||
|     public static final int DEFAULT_ORDER = -1; | ||||
|  | ||||
|     private int order = DEFAULT_ORDER; | ||||
|  | ||||
|     private static final String[] APOLLO_SYSTEM_PROPERTIES = {ConfigConsts.APOLLO_JDBC_DAO, | ||||
|             ConfigConsts.APOLLO_JDBC_URL, ConfigConsts.APOLLO_JDBC_USERNAME, ConfigConsts.APOLLO_JDBC_PASSWORD}; | ||||
|  | ||||
|     @Override | ||||
|     public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { | ||||
|         initializeSystemProperty(environment); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * To fill system properties from environment config | ||||
|      */ | ||||
|     void initializeSystemProperty(ConfigurableEnvironment environment) { | ||||
|         for (String propertyName : APOLLO_SYSTEM_PROPERTIES) { | ||||
|             fillSystemPropertyFromEnvironment(environment, propertyName); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void fillSystemPropertyFromEnvironment(ConfigurableEnvironment environment, String propertyName) { | ||||
|         if (System.getProperty(propertyName) != null) { | ||||
|             return; | ||||
|         } | ||||
|         String propertyValue = environment.getProperty(propertyName); | ||||
|         if (Strings.isNullOrEmpty(propertyValue)) { | ||||
|             return; | ||||
|         } | ||||
|         System.setProperty(propertyName, propertyValue); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public int getOrder() { | ||||
|         return order; | ||||
|     } | ||||
|  | ||||
|     public void setOrder(int order) { | ||||
|         this.order = order; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1 +0,0 @@ | ||||
| cn.iocoder.yudao.framework.apollo.internals.DefaultXInjector | ||||
| @@ -1,2 +0,0 @@ | ||||
| org.springframework.boot.env.EnvironmentPostProcessor=\ | ||||
|     cn.iocoder.yudao.framework.apollo.spring.boot.ApolloApplicationContextInitializer | ||||
| @@ -58,10 +58,6 @@ | ||||
|         </dependency> | ||||
|  | ||||
|         <!-- Config 配置中心相关 --> | ||||
|         <dependency> | ||||
|             <groupId>cn.iocoder.boot</groupId> | ||||
|             <artifactId>yudao-spring-boot-starter-config</artifactId> | ||||
|         </dependency> | ||||
|  | ||||
|         <!-- Job 定时任务相关 --> | ||||
|         <dependency> | ||||
|   | ||||
| @@ -1,42 +0,0 @@ | ||||
| package cn.iocoder.yudao.module.infra.dal.mysql.config; | ||||
|  | ||||
| import cn.hutool.core.date.LocalDateTimeUtil; | ||||
| import cn.iocoder.yudao.framework.apollo.internals.ConfigFrameworkDAO; | ||||
| import cn.iocoder.yudao.framework.apollo.internals.dto.ConfigRespDTO; | ||||
| import org.springframework.jdbc.core.JdbcTemplate; | ||||
| import org.springframework.jdbc.datasource.DriverManagerDataSource; | ||||
|  | ||||
| import javax.sql.DataSource; | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * ConfigDAOImpl 实现类 | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| public class ConfigDAOImpl implements ConfigFrameworkDAO { | ||||
|  | ||||
|     private final JdbcTemplate jdbcTemplate; | ||||
|  | ||||
|     public ConfigDAOImpl(String jdbcUrl, String username, String password) { | ||||
|         DataSource dataSource = new DriverManagerDataSource(jdbcUrl, username, password); | ||||
|         this.jdbcTemplate = new JdbcTemplate(dataSource); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public int selectCountByUpdateTimeGt(LocalDateTime maxUpdateTime) { | ||||
|         return jdbcTemplate.queryForObject("SELECT COUNT(*) FROM infra_config WHERE update_time > ?", | ||||
|                 Integer.class, maxUpdateTime); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<ConfigRespDTO> selectList() { | ||||
|         return jdbcTemplate.query("SELECT config_key, value, update_time, deleted FROM infra_config", | ||||
|                 (rs, rowNum) -> new ConfigRespDTO().setKey(rs.getString("config_key")) | ||||
|                         .setValue(rs.getString("value")) | ||||
|                         .setUpdateTime(LocalDateTimeUtil.of(rs.getDate("update_time"))) | ||||
|                         .setDeleted(rs.getBoolean("deleted"))); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,24 +0,0 @@ | ||||
| package cn.iocoder.yudao.module.infra.mq.consumer.config; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.apollo.internals.DBConfigRepository; | ||||
| import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener; | ||||
| import cn.iocoder.yudao.module.infra.mq.message.config.ConfigRefreshMessage; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.springframework.stereotype.Component; | ||||
|  | ||||
| /** | ||||
|  * 针对 {@link ConfigRefreshMessage} 的消费者 | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| @Component | ||||
| @Slf4j | ||||
| public class ConfigRefreshConsumer extends AbstractChannelMessageListener<ConfigRefreshMessage> { | ||||
|  | ||||
|     @Override | ||||
|     public void onMessage(ConfigRefreshMessage message) { | ||||
|         log.info("[onMessage][收到 Config 刷新消息]"); | ||||
|         DBConfigRepository.noticeSync(); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,4 @@ | ||||
| /** | ||||
|  * 占位符,避免缩进 | ||||
|  */ | ||||
| package cn.iocoder.yudao.module.infra.mq.consumer; | ||||
| @@ -1,17 +0,0 @@ | ||||
| package cn.iocoder.yudao.module.infra.mq.message.config; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessage; | ||||
| import lombok.Data; | ||||
|  | ||||
| /** | ||||
|  * 配置数据刷新 Message | ||||
|  */ | ||||
| @Data | ||||
| public class ConfigRefreshMessage extends AbstractChannelMessage { | ||||
|  | ||||
|     @Override | ||||
|     public String getChannel() { | ||||
|         return "infra.config.refresh"; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,4 @@ | ||||
| /** | ||||
|  * 占位符,避免缩进 | ||||
|  */ | ||||
| package cn.iocoder.yudao.module.infra.mq.message; | ||||
| @@ -1,26 +0,0 @@ | ||||
| package cn.iocoder.yudao.module.infra.mq.producer.config; | ||||
|  | ||||
| import cn.iocoder.yudao.module.infra.mq.message.config.ConfigRefreshMessage; | ||||
| import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate; | ||||
| import org.springframework.stereotype.Component; | ||||
|  | ||||
| import javax.annotation.Resource; | ||||
|  | ||||
| /** | ||||
|  * Config 配置相关消息的 Producer | ||||
|  */ | ||||
| @Component | ||||
| public class ConfigProducer { | ||||
|  | ||||
|     @Resource | ||||
|     private RedisMQTemplate redisMQTemplate; | ||||
|  | ||||
|     /** | ||||
|      * 发送 {@link ConfigRefreshMessage} 消息 | ||||
|      */ | ||||
|     public void sendConfigRefreshMessage() { | ||||
|         ConfigRefreshMessage message = new ConfigRefreshMessage(); | ||||
|         redisMQTemplate.send(message); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,4 @@ | ||||
| /** | ||||
|  * 占位符,避免缩进 | ||||
|  */ | ||||
| package cn.iocoder.yudao.module.infra.mq.producer; | ||||
| @@ -1,7 +1,6 @@ | ||||
| package cn.iocoder.yudao.module.infra.service.config; | ||||
|  | ||||
| import cn.hutool.core.util.StrUtil; | ||||
| import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; | ||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||
| import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigCreateReqVO; | ||||
| import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigExportReqVO; | ||||
| @@ -12,7 +11,6 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.config.ConfigDO; | ||||
| import cn.iocoder.yudao.module.infra.dal.mysql.config.ConfigMapper; | ||||
| import cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants; | ||||
| import cn.iocoder.yudao.module.infra.enums.config.ConfigTypeEnum; | ||||
| import cn.iocoder.yudao.module.infra.mq.producer.config.ConfigProducer; | ||||
| import com.google.common.annotations.VisibleForTesting; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.springframework.stereotype.Service; | ||||
| @@ -21,6 +19,8 @@ import org.springframework.validation.annotation.Validated; | ||||
| import javax.annotation.Resource; | ||||
| import java.util.List; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||||
|  | ||||
| /** | ||||
|  * 参数配置 Service 实现类 | ||||
|  */ | ||||
| @@ -32,9 +32,6 @@ public class ConfigServiceImpl implements ConfigService { | ||||
|     @Resource | ||||
|     private ConfigMapper configMapper; | ||||
|  | ||||
|     @Resource | ||||
|     private ConfigProducer configProducer; | ||||
|  | ||||
|     @Override | ||||
|     public Long createConfig(ConfigCreateReqVO reqVO) { | ||||
|         // 校验正确性 | ||||
| @@ -43,8 +40,6 @@ public class ConfigServiceImpl implements ConfigService { | ||||
|         ConfigDO config = ConfigConvert.INSTANCE.convert(reqVO); | ||||
|         config.setType(ConfigTypeEnum.CUSTOM.getType()); | ||||
|         configMapper.insert(config); | ||||
|         // 发送刷新消息 | ||||
|         configProducer.sendConfigRefreshMessage(); | ||||
|         return config.getId(); | ||||
|     } | ||||
|  | ||||
| @@ -54,9 +49,7 @@ public class ConfigServiceImpl implements ConfigService { | ||||
|         checkCreateOrUpdate(reqVO.getId(), null); // 不允许更新 key | ||||
|         // 更新参数配置 | ||||
|         ConfigDO updateObj = ConfigConvert.INSTANCE.convert(reqVO); | ||||
|         configMapper.updateById(updateObj); | ||||
|         // 发送刷新消息 | ||||
|         configProducer.sendConfigRefreshMessage(); | ||||
|         configMapper.updateById(updateObj);; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -65,12 +58,10 @@ public class ConfigServiceImpl implements ConfigService { | ||||
|         ConfigDO config = checkConfigExists(id); | ||||
|         // 内置配置,不允许删除 | ||||
|         if (ConfigTypeEnum.SYSTEM.getType().equals(config.getType())) { | ||||
|             throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_CAN_NOT_DELETE_SYSTEM_TYPE); | ||||
|             throw exception(ErrorCodeConstants.CONFIG_CAN_NOT_DELETE_SYSTEM_TYPE); | ||||
|         } | ||||
|         // 删除 | ||||
|         configMapper.deleteById(id); | ||||
|         // 发送刷新消息 | ||||
|         configProducer.sendConfigRefreshMessage(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -109,7 +100,7 @@ public class ConfigServiceImpl implements ConfigService { | ||||
|         } | ||||
|         ConfigDO config = configMapper.selectById(id); | ||||
|         if (config == null) { | ||||
|             throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_NOT_EXISTS); | ||||
|             throw exception(ErrorCodeConstants.CONFIG_NOT_EXISTS); | ||||
|         } | ||||
|         return config; | ||||
|     } | ||||
| @@ -122,10 +113,10 @@ public class ConfigServiceImpl implements ConfigService { | ||||
|         } | ||||
|         // 如果 id 为空,说明不用比较是否为相同 id 的参数配置 | ||||
|         if (id == null) { | ||||
|             throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_KEY_DUPLICATE); | ||||
|             throw exception(ErrorCodeConstants.CONFIG_KEY_DUPLICATE); | ||||
|         } | ||||
|         if (!config.getId().equals(id)) { | ||||
|             throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_KEY_DUPLICATE); | ||||
|             throw exception(ErrorCodeConstants.CONFIG_KEY_DUPLICATE); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -96,7 +96,7 @@ yudao: | ||||
|     version: ${yudao.info.version} | ||||
|     base-package: ${yudao.info.base-package} | ||||
|   captcha: | ||||
|     enable: true # 验证码的开关,默认为 true;注意,优先读取数据库 infra_config 的 yudao.captcha.enable,所以请从数据库修改,可能需要重启项目 | ||||
|     enable: true # 验证码的开关,默认为 true | ||||
|   codegen: | ||||
|     base-package: ${yudao.info.base-package} | ||||
|     db-schemas: ${spring.datasource.dynamic.datasource.master.name} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV