From c4c614592a4ae457923f9a6425b41b207077dc78 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 20 Jan 2021 17:12:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=86=85=E5=B5=8C=E7=9A=84?= =?UTF-8?q?=20apollo=20=E7=9A=84=E9=85=8D=E7=BD=AE=E4=B8=AD=E5=BF=83?= =?UTF-8?q?=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 7 ++ .../apollo/internals/DBConfigRepository.java | 95 +++++++++++++++++++ .../apollo/internals/DefaultXInjector.java | 75 +++++++++++++++ .../framework/apollo/package-info.java | 1 + .../framework/apollo/spi/DBConfigFactory.java | 27 ++++++ .../config/SysConfigController.java | 2 +- .../mysql/dao/permission/SysRoleMapper.java | 2 +- .../system/service/dept/SysPostService.java | 2 +- .../permission/SysPermissionService.java | 2 +- .../service/permission/SysRoleService.java | 2 +- .../permission/impl/SysRoleServiceImpl.java | 2 +- ....ctrip.framework.apollo.internals.Injector | 1 + src/main/resources/application.yaml | 8 ++ 13 files changed, 220 insertions(+), 6 deletions(-) create mode 100644 src/main/java/cn/iocoder/dashboard/framework/apollo/internals/DBConfigRepository.java create mode 100644 src/main/java/cn/iocoder/dashboard/framework/apollo/internals/DefaultXInjector.java create mode 100644 src/main/java/cn/iocoder/dashboard/framework/apollo/package-info.java create mode 100644 src/main/java/cn/iocoder/dashboard/framework/apollo/spi/DBConfigFactory.java create mode 100644 src/main/resources/META-INF/services/com.ctrip.framework.apollo.internals.Injector diff --git a/pom.xml b/pom.xml index cc04724b0..8fb46e19c 100644 --- a/pom.xml +++ b/pom.xml @@ -167,6 +167,13 @@ ${redisson.version} + + + com.ctrip.framework.apollo + apollo-client + 1.7.0 + + org.apache.skywalking 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 new file mode 100644 index 000000000..38743080a --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/framework/apollo/internals/DBConfigRepository.java @@ -0,0 +1,95 @@ +package cn.iocoder.dashboard.framework.apollo.internals; + +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 lombok.extern.slf4j.Slf4j; + +import java.util.Properties; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +@Slf4j +public class DBConfigRepository extends AbstractConfigRepository { + + private final static ScheduledExecutorService m_executorService; + + static { + m_executorService = Executors.newScheduledThreadPool(1, + ApolloThreadFactory.create(DBConfigRepository.class.getSimpleName(), true)); + } + + private final ConfigUtil m_configUtil; + + private final AtomicReference m_configCache; + private final String m_namespace; + + public DBConfigRepository(String namespace) { + // 初始化变量 + this.m_namespace = namespace; + m_configCache = new AtomicReference<>(); + m_configUtil = ApolloInjector.getInstance(ConfigUtil.class); + + // 初始化加载 + this.trySync(); + // 初始化定时任务 + this.schedulePeriodicRefresh(); + } + + private AtomicInteger index = new AtomicInteger(); + + @Override + protected void sync() { + System.out.println("我同步啦"); + + index.incrementAndGet(); + Properties properties = new Properties(); + properties.setProperty("demo.test", String.valueOf(index.get())); + m_configCache.set(properties); + super.fireRepositoryChange(m_namespace, properties); + } + + @Override + public Properties getConfig() { + // 兜底,避免可能存在配置为 null 的情况 + if (m_configCache.get() == null) { + this.trySync(); + } + // 返回配置 + return m_configCache.get(); + } + + @Override + public void setUpstreamRepository(ConfigRepository upstreamConfigRepository) { + // 啥事不做 + } + + @Override + public ConfigSourceType getSourceType() { + return ConfigSourceType.REMOTE; + } + + 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); + + // 执行同步 + trySync(); + + 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/apollo/internals/DefaultXInjector.java b/src/main/java/cn/iocoder/dashboard/framework/apollo/internals/DefaultXInjector.java new file mode 100644 index 000000000..587a850f3 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/framework/apollo/internals/DefaultXInjector.java @@ -0,0 +1,75 @@ +package cn.iocoder.dashboard.framework.apollo.internals; + +import cn.iocoder.dashboard.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.HttpUtil; +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 getInstance(Class 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 getInstance(Class 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(HttpUtil.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); + } + + } + +} diff --git a/src/main/java/cn/iocoder/dashboard/framework/apollo/package-info.java b/src/main/java/cn/iocoder/dashboard/framework/apollo/package-info.java new file mode 100644 index 000000000..f8a617005 --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/framework/apollo/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.dashboard.framework.apollo; diff --git a/src/main/java/cn/iocoder/dashboard/framework/apollo/spi/DBConfigFactory.java b/src/main/java/cn/iocoder/dashboard/framework/apollo/spi/DBConfigFactory.java new file mode 100644 index 000000000..8bc760a4b --- /dev/null +++ b/src/main/java/cn/iocoder/dashboard/framework/apollo/spi/DBConfigFactory.java @@ -0,0 +1,27 @@ +package cn.iocoder.dashboard.framework.apollo.spi; + +import cn.iocoder.dashboard.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; + +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); // TODO 芋艿:看看怎么优化 + } + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/controller/config/SysConfigController.java b/src/main/java/cn/iocoder/dashboard/modules/system/controller/config/SysConfigController.java index 7fdc7554f..45b05569c 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/controller/config/SysConfigController.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/controller/config/SysConfigController.java @@ -28,7 +28,7 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.CO @RequestMapping("/system/config") public class SysConfigController { - @Value("${demo.test:false}") + @Value("${demo.test}") private String demo; @GetMapping("/demo") diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/permission/SysRoleMapper.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/permission/SysRoleMapper.java index 615fc44ea..eb6345a8b 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/permission/SysRoleMapper.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/permission/SysRoleMapper.java @@ -8,8 +8,8 @@ import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysRo import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import org.apache.ibatis.annotations.Mapper; +import org.springframework.lang.Nullable; -import javax.annotation.Nullable; import java.util.Collection; import java.util.List; diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/SysPostService.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/SysPostService.java index 0a7168c6a..e95c7acac 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/SysPostService.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/dept/SysPostService.java @@ -6,8 +6,8 @@ import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostExport import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostPageReqVO; import cn.iocoder.dashboard.modules.system.controller.dept.vo.post.SysPostUpdateReqVO; import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysPostDO; +import org.springframework.lang.Nullable; -import javax.annotation.Nullable; import java.util.Collection; import java.util.List; diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/SysPermissionService.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/SysPermissionService.java index cab499201..60936a414 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/SysPermissionService.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/SysPermissionService.java @@ -1,8 +1,8 @@ package cn.iocoder.dashboard.modules.system.service.permission; import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysMenuDO; +import org.springframework.lang.Nullable; -import javax.annotation.Nullable; import java.util.Collection; import java.util.List; import java.util.Set; diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/SysRoleService.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/SysRoleService.java index 41a9d39ef..161a0d810 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/SysRoleService.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/SysRoleService.java @@ -6,8 +6,8 @@ import cn.iocoder.dashboard.modules.system.controller.permission.vo.role.SysRole import cn.iocoder.dashboard.modules.system.controller.permission.vo.role.SysRolePageReqVO; import cn.iocoder.dashboard.modules.system.controller.permission.vo.role.SysRoleUpdateReqVO; import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysRoleDO; +import org.springframework.lang.Nullable; -import javax.annotation.Nullable; import java.util.Collection; import java.util.List; import java.util.Set; diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysRoleServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysRoleServiceImpl.java index 1aa05485a..d98611cbf 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysRoleServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysRoleServiceImpl.java @@ -18,11 +18,11 @@ import cn.iocoder.dashboard.modules.system.service.permission.SysRoleService; import com.baomidou.mybatisplus.core.metadata.IPage; import com.google.common.collect.ImmutableMap; import lombok.extern.slf4j.Slf4j; +import org.springframework.lang.Nullable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; -import javax.annotation.Nullable; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.util.*; diff --git a/src/main/resources/META-INF/services/com.ctrip.framework.apollo.internals.Injector b/src/main/resources/META-INF/services/com.ctrip.framework.apollo.internals.Injector new file mode 100644 index 000000000..a52f206f2 --- /dev/null +++ b/src/main/resources/META-INF/services/com.ctrip.framework.apollo.internals.Injector @@ -0,0 +1 @@ +cn.iocoder.dashboard.framework.apollo.internals.DefaultXInjector diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index c38ecabbc..14248ca39 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -47,6 +47,14 @@ yudao: file: base-path: http://127.0.0.1:1024/api/file/get/ +# Apollo 配置中心 +apollo: + bootstrap: + enabled: true + eagerLoad: + enabled: true + autoUpdateInjectedSpringProperties: true + # MyBatis Plus 的配置项 mybatis-plus: configuration: