Nacos配置中心优雅配置JSON数据格式

在我业务开发中,需要在配置中心配置Json数据,返回给前端。因Nacos默认不支持Json格式配置,需要搭配监听器获取配置中心Json数据,返回给客户端。

二、搭配Nacos配置Josn数据

1. bootstrap.yml

 
server:
  port: 9000
spring:
  application:
    name: nacos-demo
  cloud:
     ## 注册中心地址
    discovery:
      server-addr: 127.0.0.1:8848
    nacos:
      config:
        #nacos地址
        server-addr: 127.0.0.1:8848
        #命名空间
        namespace: 096ad119-e2e0-4371-94c9-430b01102af2
        #配置文件类型,目前只支持yaml,yml,properties,目前不需要了
        file-extension: yaml
        #默认提供者,目前不需要了
        refresh-enabled: true
        enabled: true
        group: NACOS_DEMO

2. nacos配置-测试案例

3. 配置详情

image.png

4. NacosConfig 组装配置中心DataId

具体使用 只需要 在 NacosConfig 中nacosConfigLocalCacheInfoMap方法添加对应配置映射即可,如下

@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("testText", String.class);
        map.put("testJson1", List.class);
        map.put("testJson2", User.class);
        map.put("testInteger", Integer.class);
        return map;
    }
}

底层实现

/**
 * 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. User 用于配置映射的数据实体

@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. 测试使用

    @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;
    }

测试结果

实时修改,不停服更新配置

再看

nacos config 配置中心 至此结束!


Nacos配置代码: feign-demo→order-service-nacos

代码地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/4408.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue使用ElementUI对table的指定列进行合算

前言 最近有一个想法&#xff0c;就是记录自己花销的时候&#xff0c;table中有一项内容是花销的金额。然后想在table的底部有一项内容是该金额的总计。 然后我就顺着elementui的table组件寻找相关的demo&#xff0c;还真发现了一个这样的demo。 对于这个demo&#xff0c;官方…

SSH框架整合教程

工程目录结构如下&#xff1a; 本工程只介绍SSH整合的基本流程&#xff0c;所以没有写接口 1. 导入jar包 <dependencies><!--hibernate包--><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId>…

【各种安装2】

各种安装2一、八阶段-第四章-案例导入说明1.安装MySQL1.1.准备目录1.2.运行命令1.3.修改配置1.4.重启2.导入SQL3.导入Demo工程3.1.分页查询商品3.2.新增商品3.3.修改商品3.4.修改库存3.5.删除商品3.6.根据id查询商品3.7.根据id查询库存3.8.启动4.导入商品查询页面4.1.运行nginx…

Linux线程同步与互斥(二)/生产消费者模型

⭐前言&#xff1a;本文会先后讲解生产消费者模型、条件变量和基于阻塞队列的生产消费者模型。 1.生产消费者模型 什么是生产消费者模型&#xff1f; 认识生产消费者模型 使用学生&#xff08;消费者&#xff09;&#xff0c;超市&#xff0c;供货商&#xff08;生产者&…

C++ 26 常用算法

目录 一、概述 1.1 常用遍历算法 1.1.1 算法简介 1.1.2 for_each遍历算法 1.1.3 transform遍历算法 1.2 常用查找算法 1.2.1 算法简介 1.2.2 find 查找算法 1.2.3 find_if 查找算法 1.2.4 adjacent_find 查找算法 1.2.5 binary_search 查找算法 1.2.6 count 查找算法…

【面试题】JS的一些优雅写法 reduce和map

大厂面试题分享 面试题库 前后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 web前端面试题库 VS java后端面试题库大全 JS的一些优雅写法 reduce 1、可以使用 reduce 方法来实现对象数组中根据某一key值求和 …

LFM雷达实现及USRP验证【章节3:连续雷达测距测速】

第一章介绍了在相对速度为0时候的雷达测距原理 目录 1. LFM测速 1.1 雷达测速原理 1.2 Chrip信号测速 2. LFM测速代码实现 参数设置 仿真图像 matlab源码 代码分析 第一章介绍了在相对速度为0时候的雷达测距原理&#xff0c;第二章介绍了基于LFM的雷达测距原理及其实现…

数据结构第十一期——线段树的原理和应用

目录 一、前言 二、线段树的概念 1、区间最值问题RMQ (Range Minimum/Maximum Query) &#xff08;1&#xff09;暴力法 &#xff08;2&#xff09;高效的办法&#xff1a;线段树 &#xff08;3&#xff09;把数列放在二叉树上 &#xff08;4&#xff09;查询最小值的复…

43-二叉树练习-LeetCode236二叉树的最近公共祖先

题目 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也可以是它…

一款全新的基于GPT4的Python神器,关键还免费

chartgpt大火之后&#xff0c;随之而来的就是一大类衍生物了。 然后&#xff0c;今天要给大家介绍的是一款基于GPT4的新一代辅助编程神器——Cursor。 它最值得介绍的地方在于它免费&#xff0c;我们可以直接利用它来辅助我们编程&#xff0c;真正做到事半功倍。 注意&#…

k8s实践 | configmapsecretpvpvc

文章目录configmap&secret&pv&pvc一、configMap1、应用场景2、创建configMap2.1、help文档2.2、使用目录创建2.3、根据文件创建2.4、文字创建2.5、直接方法2.6、pod中应用2.7、热更新二、secret1、Service Account2、opaque Secret2.1、创建示例2.2、使用方式三、k…

eNSP 本地AAA配置实验

关于本实验本实验要求将路由器AR1配置为AAA服务器&#xff0c;以本地认证方式对尝试登录AR1的用户进行身份认证和授权。路由器AR2作为登录用户&#xff08;AAA客户端&#xff09;&#xff0c;以Telnet的方式登录AR1.读者需要在AR1中创建一个名为datacom的管理员域&#xff0c;并…

【Unity游戏开发教程】零基础带你从小白到超神22——旧动画和新动画组件的使用

制作一个动画 创建动画 添加变化属性 实现方块向右移动10 添加关键帧 实现先慢后快的效果 录制动画 旧动画组件(Animation组件) 如果想让一个游

PMP项管2023年5月的备考准备攻略!

2023年共有4次PMP考试&#xff0c;分别是3月、5月、8月、11月&#xff0c;由于3月份考试不开放新报名&#xff0c;所以第一次备考PMP的同学可以选择参加5月份考试。那么&#xff0c;现在备考5月份PMP考试还来得及吗&#xff1f; 现在开始备考5月PMP考试&#xff0c;时间是非常…

GEE:克里金 Kriging 插值(以陕西省2013年生物量为例)

本文记录了在Google Earth Engine(GEE)平台上进行 Kriging 插值的介绍和代码案例。本文通过选取的2013年陕西省生物量样本点数据为例,利用 Kriging 插值对未知区域做了插值计算。 Google Earth Engine(GEE)是一个用于分析地理空间数据的云平台,其中包含了许多地理空间分…

Office E5 OneDrive API使用指南:注册+密钥获取+获取临时上传链接+分片

异想之旅&#xff1a;本人原创博客完全手敲&#xff0c;绝对非搬运&#xff0c;全网不可能有重复&#xff1b;本人无团队&#xff0c;仅为技术爱好者进行分享&#xff0c;所有内容不牵扯广告。本人所有文章仅在CSDN、掘金和个人博客&#xff08;一定是异想之旅域名&#xff09;…

Java 各种锁的理解与实现

1. volatile 是轻量级锁&#xff1a; 只能修饰在变量上&#xff0c;使得 cpu 每次对于该变量的修改和读取都从内存中操作&#xff0c;而不是从CPU cache 中操作&#xff0c;保证共享变量对所有线程的可见性&#xff0c;但是并不能保证原子性 2. synchronized 悲观锁&#xff…

Mybatis的CRUD使用详解

文章目录一.Mybatis的CRUD使用详解1.1 select1.2 insert1.3 update1.3 delete二.常见错误一.Mybatis的CRUD使用详解 注意&#xff1a;增删改需要提交事务。 namespace&#xff08;UserMapper.xml&#xff09; namespace中的包名需要和Dao/mapper接口的包名一致。 <!--na…

论文阅读 10 | Instance Credibility Inference for Few-Shot Learning

小样本学习的实例可信度推理作者摘要1. Introduction2. Related Work作者 摘要 小样本学习&#xff08;FSL&#xff09;旨在识别每个类别极其有限的训练数据的新对象。以前的努力是通过利用元学习范式或数据增强中的新原理来缓解这个极其缺乏数据的问题。相比之下&#xff0c;本…

taro--之使用nutui组件库

安装 Taro 脚手架# 使用 npm 安装 CLI npm install -g tarojs/cli# 使用 yarn 安装 CLI yarn global add tarojs/cli# 使用 cnpm 安装 CLI cnpm install -g tarojs/cli使用 NutUI 模板创建项目1、使用命令创建 Taro 项目&#xff1a;taro init myApp2、按照下方图片依次选择&am…