一、 概述
需要在配置中心配置Json数据,返回给前端。因Nacos默认不支持Json格式配置,需要搭配监听器获取配置中心Json数据,返回给客户端。
二、搭配Nacos配置Josn数据
1. bootstrap.yml
server: port: 9000 spring: application: name: robot-system cloud: nacos: discovery: server-addr: 10.101.80.10:8848 config: server-addr: 10.5.24.28:8848 namespace: ba28cf53-23ae-4d54-b518-9f29e6f26d87 refresh-enabled: true enabled: true
2. nacos配置-测试案例
3. 配置详情
1 2 3 4 均为json数据
4. NacosConfig 组装配置中心DataId
@Configuration public class NacosConfig { /** * 前提条件 要求 serverAddr、namespace、group使用bootstrap.yml 中 spring cloud nacos config 的。 * @return */ @Bean public Map<String, Class> nacosConfigLocalCacheInfoMap() { // key:dataId, value:对应数据类型 Map<String, Class> map = new HashMap<>(); map.put("robotEnvConfig", String.class); map.put("robotId-iben_a03_1", IBen.class); map.put("robotId-dapang_ww", IBen.class); map.put("robotId-x_biped_upper_part_0", IBen.class); return map; } }
5. 底层实现过程
/** * nacos 配置 信息 */ public class NacosConfigInfo { public NacosConfigInfo(String serverAddr, String namespace, String group, String dataId, boolean refresh, Class cls) { this.serverAddr = serverAddr; this.namespace = namespace; this.group = group; this.dataId = dataId; this.refresh = refresh; this.cls = cls; } public NacosConfigInfo() { } private String serverAddr; private String namespace; private String group; private String dataId; private boolean refresh = true; private Class cls = String.class; public String getServerAddr() { return serverAddr; } public void setServerAddr(String serverAddr) { this.serverAddr = serverAddr; } public String getNamespace() { return namespace; } public void setNamespace(String namespace) { this.namespace = namespace; } public String getGroup() { return group; } public void setGroup(String group) { this.group = group; } public String getDataId() { return dataId; } public void setDataId(String dataId) { this.dataId = dataId; } public boolean isRefresh() { return refresh; } public void setRefresh(boolean refresh) { this.refresh = refresh; } public Class getCls() { return cls; } public void setCls(Class cls) { this.cls = cls; } public long getTimeout() { return 5000L; } }
6. NacosConfigLocalCatch 核心监听触发类
@Component public class NacosConfigLocalCatch implements InitializingBean { private Map<String, Object> localCatchMap = new HashMap<>(); @Resource(name = "nacosConfigLocalCacheInfoMap") private Map<String, Class> nacosConfigLocalCacheInfoMap; @Autowired private NacosConfigProperties nacosConfigProperties; private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 2, 4, 1, TimeUnit.SECONDS, new LinkedBlockingDeque<>(100), new ThreadPoolExecutor.CallerRunsPolicy() ); protected final Logger logger = LoggerFactory.getLogger(getClass()); protected final String clazzSimpleName = getClass().getSimpleName(); @Override public void afterPropertiesSet() throws Exception { nacosConfigLocalCacheInfoMap.forEach((k, v) -> { NacosConfigInfo nacosConfigInfo = new NacosConfigInfo(nacosConfigProperties.getServerAddr(), nacosConfigProperties.getNamespace(), nacosConfigProperties.getGroup(), k, true, nacosConfigLocalCacheInfoMap.get(k)); this.listener(nacosConfigInfo); }); } public void listener(NacosConfigInfo nacosConfigInfo) { Listener listener = new Listener() { @Override public Executor getExecutor() { return threadPoolExecutor; } @Override public void receiveConfigInfo(String configInfo) { logger.info("{}#receiveConfigInfo receive configInfo. configInfo={}", clazzSimpleName, configInfo); compile(configInfo, nacosConfigInfo); } }; ConfigService configService = this.getConfigService(nacosConfigInfo); String config = null; try { config = configService.getConfig(nacosConfigInfo.getDataId(), nacosConfigInfo.getGroup(), nacosConfigInfo.getTimeout()); logger.info("{}#afterPropertiesSet init configInfo. configInfo={}", clazzSimpleName, config); // 初始化 compile(config, nacosConfigInfo); // 监听 configService.addListener(nacosConfigInfo.getDataId(), nacosConfigInfo.getGroup(), listener); } catch (NacosException e) { e.printStackTrace(); throw new RuntimeException("nacos server 监听 异常! dataId = " + nacosConfigInfo.getDataId()); } } private void compile(String config, NacosConfigInfo nacosConfigInfo) { Object initValue = JSON.parseObject(config, nacosConfigInfo.getCls()); localCatchMap.put(nacosConfigInfo.getDataId(), initValue); } /** * 获取ConfigService * * @return */ private ConfigService getConfigService(NacosConfigInfo nacosConfigInfo) { String serverAddr = nacosConfigInfo.getServerAddr(); String nameSpace = nacosConfigInfo.getNamespace(); Properties properties = new Properties(); properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr); properties.put(PropertyKeyConst.NAMESPACE, nameSpace); ConfigService configService; try { configService = NacosFactory.createConfigService(properties); } catch (NacosException e) { e.printStackTrace(); throw new RuntimeException("Nacos config 配置 异常"); } return configService; } public <T> T get(String dataId, Class<T> cls) { if (cls != nacosConfigLocalCacheInfoMap.get(dataId)) { throw new IllegalArgumentException("类型异常"); } return (T) localCatchMap.get(dataId); } }
7. 用于配置映射的数据实体
@Data public class IBen { private String envType; @Override public String toString() { final StringBuilder sb = new StringBuilder("Iben{"); sb.append("envType=").append(envType).append("}"); return sb.toString(); } }
8. 测试使用
@Test public void getInfo() { log.info("-------------------test------------------"); String text = nacosConfigLocalCatch.get("robotEnvConfig", String.class); IBen iBen1 = nacosConfigLocalCatch.get("robotId-iben_a03_1", IBen.class); IBen iBen2 = nacosConfigLocalCatch.get("robotId-dapang_ww", IBen.class); IBen iBen3 = nacosConfigLocalCatch.get("robotId-x_biped_upper_part_0", IBen.class); System.out.println("text = " + text); System.out.println("iBen1 = " + iBen1.getEnvType()); System.out.println("iBen2 = " + iBen2.getEnvType()); System.out.println("iBen3 = " + iBen3.getEnvType()); }
可以读取json配置的属性