Nacos configuration center elegantly configures JSON data format

In my business development, I need to configure Json data in the configuration center and return it to the front end. Because Nacos does not support Json format configuration by default, it is necessary to use a listener to obtain Json data from the configuration center and return it to the client.

Second, configure Josn data with Nacos

1. bootstrap.yml

server:
  port: 9000
spring:
  application:
    name: nacos-demo
  cloud:
     ## Registry address
    discovery:
      server-addr: 127.0.0.1:8848
    nacos:
      config:
        #nacos address
        server-addr: 127.0.0.1:8848
        #Namespaces
        namespace: 096ad119-e2e0-4371-94c9-430b01102af2
        #Configuration file type, currently only supports yaml, yml, properties, currently not needed
        file-extension: yaml
        #Default provider, currently not needed
        refresh-enabled: true
        enabled: true
        group: NACOS_DEMO

2. nacos configuration-test case

3. Configuration details

image.png

4. NacosConfig Assembly Configuration Center DataId

For specific use, you only need to add the corresponding configuration map in the nacosConfigLocalCacheInfoMap method in NacosConfig, as follows

@Configuration
public class NacosConfig {
    /**
     * Preconditions require serverAddr, namespace, and group to use the spring cloud nacos config in bootstrap.yml.
     * @return
     */
    @Bean
    public Map<String, Class> nacosConfigLocalCacheInfoMap() {
        // key: dataId, value: corresponding data type
        Map<String, Class> map = new HashMap<>();
        map.put("testText", String.class);
        map.put("testJson1", List.class);
        map.put("testJson2", User.class);
        map.put("testInteger", Integer.class);
        return map;
    }
}

underlying implementation

/**
 * nacos configuration information
 */
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 core monitoring trigger class

@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);
            // initialization
            compile(config, nacosConfigInfo);
            // listen
            configService.addListener(nacosConfigInfo.getDataId(), nacosConfigInfo.getGroup(), listener);
        } catch (NacosException e) {
            e.printStackTrace();
            throw new RuntimeException("nacos server monitoring exception! dataId = " + nacosConfigInfo.getDataId());
        }
    }
 
    private void compile(String config, NacosConfigInfo nacosConfigInfo) {
        Object initValue = JSON.parseObject(config, nacosConfigInfo.getCls());
        localCatchMap.put(nacosConfigInfo.getDataId(), initValue);
    }
 
    /**
     * Get 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 configuration exception");
        }
        return configService;
    }
 
    public <T> T get(String dataId, Class<T> cls) {
        if (cls != nacosConfigLocalCacheInfoMap.get(dataId)) {
            throw new IllegalArgumentException("type exception");
        }
 
        return (T) localCatchMap. get(dataId);
    }
 
}

7. User is used to configure the data entity for mapping

@Data
public class User {
 
    private String name;
    private String phone;
    private Integer age;
  
    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("User{");
        sb.append("name='").append(name).append('\'');
        sb.append(", phone='").append(phone).append('\'');
        sb.append(", age=").append(age);
        sb.append('}');
        return sb.toString();
    }
}

8. Test use

 @Autowired
    private NacosConfigLocalCatch nacosConfigLocalCatch;
 
    @RequestMapping("/test2")
    public String test2() {
        logger.info("-------------test2---------------");
        String testText = nacosConfigLocalCatch.get("testText", String.class);
        List testJson1 = nacosConfigLocalCatch.get("testJson1", List.class);
        User testJson2 = nacosConfigLocalCatch.get("testJson2", User.class);
        Integer testInteger = nacosConfigLocalCatch.get("testInteger", Integer.class);
        return testText + " , " + testJson1 + " , " + testJson2 + " , " + testInteger;
    }

Test Results

Real-time modification, non-stop update configuration

Look again

The nacos config configuration center is over!

Nacos configuration code: feign-demo→order-service-nacos

code address