SpringBoot读取自定义格式的Nacos配置
在开发的过程中,如果遇到一些特殊情况,例如Java项目读取.net项目的配置问题,由于.net项目的配置文件是非标准格式(yaml、json等)的自定义文件,需要springboot项目读取自定义格式的nacos配置文件;由于springboot不知道直接读取,故需求使用一些其他方法;以下是springboot读取.net的配置文件的live-common-setting自定义配置文件的案例
自定义Nacos加载Bean
自定义一个bean,该bean实现InitializingBean接口的afterPropertiesSet()
public class NacosConfigLocalCatch implements InitializingBean {/*** 实现加载Nacos配置的逻辑*/@Overridepublic void afterPropertiesSet() {}
}
自定义一个监听器,用于监听远程nacos变更
Listener listener=new Listener(){@Overridepublic Executor getExecutor() {return threadPoolExecutor;}@Overridepublic void receiveConfigInfo(String configInfo) {log.info("{}#receiveConfigInfo receive configInfo. configInfo={}", configInfo);compile(configInfo, nacosConfigInfo);}}
自定义一个Nacos配置载体
package com.vzan.config.securityurl;import lombok.Data;/*** @author 欧益强* @date 2023年11月13日 下午2:14:37*/
@Data
public class NacosConfigInfo {private String serverAddr;private String namespace;private String group;private String dataId;private boolean refresh = true;public NacosConfigInfo() {}public NacosConfigInfo(String serverAddr, String namespace, String group, String dataId, boolean refresh) {this.serverAddr = serverAddr;this.namespace = namespace;this.group = group;this.dataId = dataId;this.refresh = refresh;}public long getTimeout() {return 5000L;}}
获取监听bean完整类
/****/
package com.vzan.config.securityurl;import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.google.common.collect.Lists;import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.StringUtils;import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;/*** @author eakom* @date 2023年11月13日 下午2:11:46*/
@Slf4j
public class NacosConfigLocalCatch implements InitializingBean {/*** 定义需要获取nacos配置的dataId*/private List<String> nacosConfigLocalCacheInfoList = Lists.newArrayList("live-common-setting");/*** 定义一个map,存在配置到本定*/private Map<String, String> localCatchMap = new HashMap<>();@Resourceprivate NacosConfigProperties nacosConfigProperties;private static ThreadPoolExecutor threadPoolExecutor;/*** 初始化线程*/static {threadPoolExecutor = new ThreadPoolExecutor(2, 4, 1, TimeUnit.SECONDS, new LinkedBlockingDeque<>(100),new ThreadPoolExecutor.CallerRunsPolicy());}/*** 实现加载Nacos配置的逻辑*/@Overridepublic void afterPropertiesSet() {nacosConfigLocalCacheInfoList.forEach(k -> {NacosConfigInfo nacosConfigInfo = new NacosConfigInfo(nacosConfigProperties.getServerAddr(),nacosConfigProperties.getNamespace(), nacosConfigProperties.getGroup(), k, true);this.intNacosConfig(nacosConfigInfo);});}/*** 获取ConfigService* * @param nacosConfigInfo NacosConfigInfo* @return configService*/private ConfigService getConfigService(NacosConfigInfo nacosConfigInfo) {String serverAddr = nacosConfigInfo.getServerAddr();String nameSpace = nacosConfigInfo.getNamespace();Properties properties = new Properties();properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);if (!StringUtils.isEmpty(nameSpace)) {properties.put(PropertyKeyConst.NAMESPACE, nameSpace);}ConfigService configService;try {configService = NacosFactory.createConfigService(properties);} catch (NacosException e) {e.printStackTrace();throw new RuntimeException("Nacos config 配置 异常");}return configService;}/*** 初始化Nacos配置* @param nacosConfigInfo*/private void intNacosConfig(NacosConfigInfo nacosConfigInfo) {ConfigService configService = this.getConfigService(nacosConfigInfo);try {String config = configService.getConfig(nacosConfigInfo.getDataId(), nacosConfigInfo.getGroup(),nacosConfigInfo.getTimeout());log.info("{}#afterPropertiesSet init configInfo. configInfo={}", config);// 初始化compile(config, nacosConfigInfo);// 监听configService.addListener(nacosConfigInfo.getDataId(), nacosConfigInfo.getGroup(), new Listener(){@Overridepublic Executor getExecutor() {return threadPoolExecutor;}@Overridepublic void receiveConfigInfo(String configInfo) {log.info("{}#receiveConfigInfo receive configInfo. configInfo={}", configInfo);compile(configInfo, nacosConfigInfo);}});} catch (NacosException e) {e.printStackTrace();throw new RuntimeException("nacos server 监听 异常! dataId = " + nacosConfigInfo.getDataId());}}/*** 加载nacos配置到本定环境* @param config* @param nacosConfigInfo*/private void compile(String config, NacosConfigInfo nacosConfigInfo) {if ("live-common-setting".equals(nacosConfigInfo.getDataId())) {LiveCommonSetting json = JSONUtil.toBean(config, LiveCommonSetting.class);if (json == null) {log.error("common配置解析失败");return;}}localCatchMap.put(nacosConfigInfo.getDataId(), config);}public String get(String dataId) {return localCatchMap.get(dataId);}/***获取配置*/public LiveCommonSetting getLiveCommonSetting() {String config = localCatchMap.get("live-common-setting");LiveCommonSetting fromJson = JSONUtil.toBean(config, LiveCommonSetting.class);return fromJson;}}
初始化bean
@Configuration(proxyBeanMethods = false)
public class SecurityUrlConfig {@Bean@ConditionalOnProperty(value = "enabled.securityUrl",matchIfMissing = false)public NacosConfigLocalCatch initNacosConfigLocalCatch() {NacosConfigLocalCatch config=new NacosConfigLocalCatch();return config;}
}
代码中读取配置直接getLiveCommonSetting() 这个方法即可。
