Nacos学习笔记-占位符读取其他命名空间内容

news2025/3/10 9:22:35
Nacos当前命名空间下的配置文件需要跨命名空间读取其他配置文件的内容。可以先通过Nacos提供的API接口获取配置文件内容,然后解析数据将其放入环境的PropertySource中。
  • 相关依赖包
<!-- Nacos依赖包 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2.2.6.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>2.2.6.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    <version>2.3.0</version>
</dependency>
  • 部分代码

@Order(Ordered.HIGHEST_PRECEDENCE)
public class NacosEnvironmentPostProcessor implements EnvironmentPostProcessor {

    private static final String NACOS_PROPERTY_SOURCE_NAME = "NACOS";

    private static final String[] dataIds = new String[]{"db-sample.yml"};

    private static final String LOGIN_URL = "http://$host/nacos/v1/auth/users/login";

    private static final String CONFIGS_URL = "http://$host/nacos/v1/cs/configs?dataId=&group=&appName=&config_tags=&pageNo=1&pageSize=100&tenant=$tenant&search=blur&accessToken=$accessToken";

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        if (environment instanceof StandardServletEnvironment || environment instanceof StandardReactiveWebEnvironment) {
            return;
        }
        addPropertySource(environment);
    }

    private void addPropertySource(ConfigurableEnvironment environment) {
        Map<String, Object> systemEnvironment = environment.getSystemEnvironment();
        Object namespaceIdObj = systemEnvironment.get("NACOS_NAMESPACE");
        if (null == namespaceIdObj) {
            return;
        }

        String host = String.valueOf(systemEnvironment.get("NACOS_HOST"));
        String username = String.valueOf(systemEnvironment.get("NACOS_USERNAME"));
        String password = String.valueOf(systemEnvironment.get("NACOS_PASSWORD"));
        String group = String.valueOf(systemEnvironment.get("NACOS_GROUP"));
        String namespaceId = String.valueOf(namespaceIdObj);
        log.info("{} {} {} {} {}", host, username, password, group, namespaceId);

        processV2(environment, host, username, password, namespaceId);
    }

    private void processV1(ConfigurableEnvironment environment, String host, String username, String password,
            String namespaceId, String group) {
        NacosConfigProperties nacosConfigProperties = new NacosConfigProperties();
        nacosConfigProperties.setEnvironment(new StandardEnvironment());
        nacosConfigProperties.setServerAddr(host);
        nacosConfigProperties.setUsername(username);
        nacosConfigProperties.setPassword(password);
        nacosConfigProperties.setNamespace(namespaceId);
        nacosConfigProperties.setGroup(group);

        ConfigService configService = null;
        try {
            configService = NacosFactory.createConfigService(nacosConfigProperties.assembleConfigServiceProperties());
        } catch (NacosException e) {
            log.error(e.getMessage(), e);
        }

        if (null == configService) {
            return;
        }

        Properties properties = new Properties();

        for (String dataId : dataIds) {
            addProperties(dataId, getPropertySources(configService, dataId, group), properties);
        }

        environment.getPropertySources().addFirst(new PropertiesPropertySource(NACOS_PROPERTY_SOURCE_NAME, properties));
    }

    private List<PropertySource<?>> getPropertySources(ConfigService configService, String dataId, String group) {
        List<PropertySource<?>> propertySources = null;
        try {
            String config = configService.getConfig(dataId, group, 10000);
            log.info("{} {} config {}", dataId, group, config);
            propertySources = NacosDataParserHandler.getInstance().parseNacosData(dataId, config, null);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return propertySources;
    }

    private void processV2(ConfigurableEnvironment environment, String host, String username, String password,
            String namespaceId) {
        if (null != host && host.contains(",")) {
            host = host.split(",")[0];
        }

        Map<String, String> params = new HashMap<>();
        params.put("username", username);
        params.put("password", password);
        String loginResp = HttpClientUtils.sendPost(LOGIN_URL.replace("$host", host), params, "UTF-8");
        log.info("login response {}", loginResp);
        LoginDTO loginDTO = JsonUtils.json(loginResp, LoginDTO.class);
        if (null == loginDTO) {
            return;
        }

        String configsResp = HttpClientUtils.sendGet(CONFIGS_URL.replace("$host", host)
            .replace("$tenant", namespaceId).replace("$accessToken", loginDTO.getAccessToken()), "UTF-8");
        ConfigDTO configDTO = JsonUtils.json(configsResp, ConfigDTO.class);
        if (null == configDTO) {
            return;
        }

        List<ConfigDTO.Item> pageItems = configDTO.getPageItems();
        if (null == pageItems) {
            return;
        }

        Properties properties = new Properties();

        pageItems.forEach(item -> addProperties(item.getDataId(), getPropertySources(item), properties));

        environment.getPropertySources().addFirst(new PropertiesPropertySource(NACOS_PROPERTY_SOURCE_NAME, properties));
    }

    private List<PropertySource<?>> getPropertySources(ConfigDTO.Item item) {
        List<PropertySource<?>> propertySources = null;
        try {
            propertySources = NacosDataParserHandler.getInstance().parseNacosData(item.getDataId(), item.getContent(), null);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return propertySources;
    }

    private void addProperties(String dataId, List<PropertySource<?>> propertySources, Properties properties) {
        if (null == propertySources || propertySources.isEmpty()) {
            return;
        }
        propertySources.forEach(propertySource -> {
            Object source = propertySource.getSource();
            if (source instanceof Map) {
                Map<String, Object> map = (Map) source;
                map.forEach((key, value) -> {
                    if (!key.equals("spring.application.name") && !key.startsWith("server")) {
                        int i = dataId.lastIndexOf(".");
                        if (i != -1) {
                            properties.setProperty(dataId.substring(0, i + 1) + key, String.valueOf(value));
                        }
                    }
                });
            }
        });
    }

}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OSPF报文分析

OSPF报文分析 组播地址 224.0.0.0&#xff5e;224.0.0.255为预留的组播地址&#xff08;永久组地址&#xff09;&#xff0c;地址224.0.0.0保留不做分配&#xff0c;其它地址供路由协议使用&#xff1b; 224.0.1.0&#xff5e;238.255.255.255为用户可用的组播地址&#xff08;…

MySql性能(9)- mysql的order by的工作原理

全字段排序rowid排序全字段排序和rowid排序 3.1 联合索引优化 3.2 覆盖索引优化优先队列算法优化建议 5.1 修改系统参数 5.2 优化sql 1. 全字段排序 CREATE TABLE t ( id int(11) NOT NULL,city varchar(16) NOT NULL, name varchar(16) NOT NULL, age int(11) NOT NULL,addr v…

爬虫案例七Python协程爬取视频

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Python协程爬取视频 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 爬虫案例七协程爬取视频 提示&#xff1a;以下是本篇文章正文…

智慧城市智慧社区项目建设方案

一、项目背景 在全球化进程加速的今天&#xff0c;城市化问题日益凸显&#xff0c;传统的城市管理模式已难以满足现代社会对高效、智能化管理的需求。智慧城市和智慧社区的概念应运而生&#xff0c;其核心目标是通过信息技术手段&#xff0c;提升城市资源的利用效率&#xff0…

RabbitMQ高级特性--消息确认机制

目录 一、消息确认 1.消息确认机制 2.手动确认方法 二、代码示例 1. AcknowledgeMode.NONE 1.1 配置文件 1.2 生产者 1.3 消费者 1.4 运行程序 2.AcknowledgeMode.AUTO 3.AcknowledgeMode.MANUAL 一、消息确认 1.消息确认机制 生产者发送消息之后&#xff0c;到达消…

Java EE 进阶:Spring IoCDI

IOC的简单介绍 什么是Spring&#xff1f;Spring是一个开源的框架&#xff0c;让我们的开发更加的简单&#xff0c;我们可以用一句更加具体的话来概括Spring&#xff0c;就是Spring是一个包含众多工具方法的IOC容器。 简单介绍一下IOC&#xff0c;我们之前说过通过ReqestContr…

Java数据结构第二十期:解构排序算法的艺术与科学(二)

专栏&#xff1a;Java数据结构秘籍 个人主页&#xff1a;手握风云 目录 一、常见排序算法的实现 1.1. 直接选择排序 1.2. 堆排序 1.3. 冒泡排序 1.4. 快速排序 一、常见排序算法的实现 1.1. 直接选择排序 每⼀次从待排序的数据元素中选出最小的⼀个元素&#xff0c;存放在…

【算法day5】最长回文子串——马拉车算法

最长回文子串 给你一个字符串 s&#xff0c;找到 s 中最长的 回文 子串。 https://leetcode.cn/problems/longest-palindromic-substring/description/ 算法思路&#xff1a; class Solution { public:string longestPalindrome(string s) {int s_len s.size();string tmp …

《如何排查Linux系统平均负载过高》

【系统平均负载导读】何为系统平均负载&#xff1f;假设一台云服务主机&#xff0c;突然之间响应用户请求的时间变长了&#xff0c;那么这个时候应该如何去排查&#xff1f;带着这个问题&#xff0c;我们对“平均负载”展开深入的探讨和研究。 何为Linux系统的平均负载&#xf…

基于DeepSeek实现PDF嵌入SVG图片无损放大

1. PDF中效果图 2. 询问Deepseek进行代码书写&#xff0c;不断优化后结果 /*** SVG工具类&#xff0c;用于生成价格趋势的SVG图表*/ public class SvgUtils {// SVG画布尺寸private static final int WIDTH 800;private static final int HEIGHT 500;private static final i…

整型的不同类型和溢出

一、整数的不同类型 不同编程语言中的整数类型主要通过以下两个维度区分&#xff1a; 1. 存储大小 字节数&#xff1a;决定整数能表示的范围&#xff08;如 1字节8位&#xff09;。 常见类型&#xff1a; byte&#xff08;1字节&#xff09;、short&#xff08;2字节&#x…

使用express创建服务器保存数据到mysql

创建数据库和表结构 CREATE DATABASE collect;USE collect;CREATE TABLE info (id int(11) NOT NULL AUTO_INCREMENT,create_date bigint(20) DEFAULT NULL COMMENT 时间,type varchar(20) DEFAULT NULL COMMENT 数据分类,text_value text COMMENT 内容,PRIMARY KEY (id) ) EN…

小程序 wxml 语法 —— 41列表渲染 - 进阶用法

这一节讲解列表渲染的两个进阶用法&#xff1a; 如果需要对默认的变量名和下标进行修改&#xff0c;可以使用 wx:for-item 和 wx:for-item&#xff1a; 使用 wx:for-item 可以指定数组当前元素的变量名使用 wx:for-index 可以指定数组当前下标的变量名 将 wx:for 用在 标签上&…

python语言总结(持续更新)

本文主要是总结各函数&#xff0c;简单的函数不会给予示例&#xff0c;如果在平日遇到一些新类型将会添加 基础知识 输入与输出 print([要输出的内容])输出函数 input([提示内容]如果输入提示内容会在交互界面显示&#xff0c;用以提示用户)输入函数 注释 # 单行注释符&…

FPGA学习篇——Verilog学习5(reg,wire区分及模块例化)

1 何时用reg&#xff0c;何时用wire&#xff1f; 这个我找了一些网上的各种资料&#xff0c;大概说一下自己的理解&#xff0c;可能还不太到位... wire相当于一根线&#xff0c;是实时传输的那种&#xff0c;而reg是一个寄存器&#xff0c;是可以存储数据的&#xff0c;需要立…

Redis 数据持久化之AOF

AOF&#xff08;Append Only File&#xff09; 以日志的形式来记录每个写操作&#xff0c;将Redis执行过的所有写指令记录下来&#xff08;读操作不记录&#xff09;&#xff0c;只许追加文件但不可以改写文件&#xff0c;redis启动之初会读取该文件重新构建数据&#xff0c;换…

【芯片验证】verificationguide上的74道SystemVerilog面试题

诧异啊,像我这种没事在网上各处捡东西吃的人为什么之前一直没有用过verificationguide这个网站呢?总不能是大家都已经看过就留下我不知道吧。前几天在论坛上和朋友谈论验证面试题时才搜到这个网站的,感觉挺有意思: .: Verification Guide :.​verificationguide.com/https…

Java后端高频面经——计算机网络

TCP/IP四层模型&#xff1f;输入一个网址后发生了什么&#xff0c;以百度为例&#xff1f;&#xff08;美团&#xff09; &#xff08;1&#xff09;四层模型 应用层&#xff1a;支持 HTTP、SMTP 等最终用户进程传输层&#xff1a;处理主机到主机的通信&#xff08;TCP、UDP&am…

面试题(二)--Object中的常见方法

Object Java的Object是所有Java类的父类&#xff0c;所有的Java类直接或者间接的继承了Object类&#xff0c;Object类位于java.lang包中&#xff08;编译时自动导入&#xff09;&#xff0c;主要提供了11种方法。 /*** native 方法&#xff0c;用于返回当前运行时对象的 Class…

运行OpenManus项目(使用Conda)

部署本项目需要具备一定的基础&#xff1a;Linux基础、需要安装好Anaconda/Miniforge&#xff08;Python可以不装好&#xff0c;直接新建虚拟环境的时候装好即可&#xff09;&#xff0c;如果不装Anaconda或者Miniforge&#xff0c;只装过Python&#xff0c;需要确保Python是3.…