SpringBoot整合Nacos

news2025/1/10 2:27:50

文章目录

    • nacos
      • nacos下载
      • nacos启动
      • nacos相关配置
        • demo-dev.yaml
        • demo-test.yaml
        • user.yaml
    • 代码
      • pom.xml
      • UserConfig
      • BeanAutoRefreshConfigExample
      • ValueAnnotationExample
      • DemoApplication
      • bootstrap.yml
      • 测试结果
      • 补充.刷新静态配置

nacos

nacos下载

下载地址

一键傻瓜试安装即可,官网写的很清楚这里不在赘述 http://nacos.io/zh-cn/docs/v2/quickstart/quick-start.html

nacos启动

将模式改为单机模式

请添加图片描述

启动成功

请添加图片描述

nacos相关配置

请添加图片描述

demo-dev.yaml
server:
  port: 8001

config:
  info: "config info for dev from nacos config center"
demo-test.yaml
server:
  port: 3333

config:
  info: "config info for test from nacos config center"
user.yaml
user:
  name: zs1112222
  age: 10
  address: 测试地址

请添加图片描述

代码

整合nacos配置中心,注册中心,完整项目地址 gitee地址

pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.2.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        <version>2.2.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        <version>2.2.2.RELEASE</version>
    </dependency>
</dependencies>

UserConfig

@Data
@Configuration
@ConfigurationProperties(prefix = "user")
public class UserConfig {

    private String name;

    private Integer age;

    private String address;

}

BeanAutoRefreshConfigExample

@RestController
public class BeanAutoRefreshConfigExample {

    @Autowired
    private UserConfig userConfig;

    @GetMapping("/user/hello")
    public String hello(){
        return userConfig.getName() + userConfig.getAge() + userConfig.getAddress();
    }

}

ValueAnnotationExample

@RestController
@RefreshScope
public class ValueAnnotationExample {

    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/config/info")
    public String getConfigInfo() {
        return configInfo;
    }

}

DemoApplication

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

bootstrap.yml

spring:
  profiles:
    # 指定环境 切换环境
    active: dev
  application:
    name: demo
  cloud:
    # nacos server dataId
    # ${spring.application.name)}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
    nacos:
      # Nacos服务注册中心
      discovery:
        serverAddr: @serverAddr@
        group: DEMO_GROUP
        namespace: 25af15f3-ae79-41c3-847d-960adb953185
        username: @username@
        password: @password@
      # Nacos作为配置中心
      config:
        server-addr: @serverAddr@
        file-extension: yaml
        group: DEMO_GROUP
        namespace: 25af15f3-ae79-41c3-847d-960adb953185
        username: @username@
        password: @password@
        # 加载多配置
        extension-configs:
          - data-id: user.yaml
            group: DEMO_GROUP
            refresh: true

测试结果

请添加图片描述

请添加图片描述

补充.刷新静态配置

有时候一些老项目或者一些写法会遇到静态的配置,这时候可以利用Java的反射特性来刷新静态变量.

大致原理为: 监听nacos配置改动,通过nacos改动确定改动的配置,进而缩小更新范围,通过反射更新变量.

<!-- https://mvnrepository.com/artifact/com.purgeteam/dynamic-config-spring-boot-starter -->
<dependency>
    <groupId>com.purgeteam</groupId>
    <artifactId>dynamic-config-spring-boot-starter</artifactId>
    <version>0.1.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

@NacosRefreshStaticField

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NacosRefreshStaticField {

    String configPrefix() default "";

}

NacosListener

@Slf4j
@Component
@EnableDynamicConfigEvent
public class NacosListener implements ApplicationListener<ActionConfigEvent> {

    @Autowired
    private ApplicationContext applicationContext;

    @SneakyThrows
    @Override
    public void onApplicationEvent(ActionConfigEvent environment) {
        Map<String, HashMap> map = environment.getPropertyMap();
        for (Map.Entry<String, HashMap> entry : map.entrySet()) {
            String key = entry.getKey();
            Map changeMap = entry.getValue();
            String before = String.valueOf(changeMap.get("before"));
            String after = String.valueOf(changeMap.get("after"));
            log.info("配置[key:{}]被改变,改变前before:{},改变后after:{}",key,before,after);

            String[] configNameArr = key.split("\\.");
            String configPrefix = configNameArr[0];
            String configRealVal = configNameArr[configNameArr.length-1];

            AtomicReference<Class<?>> curClazz = new AtomicReference<>();
            Map<String, Object> refreshStaticFieldBeanMap = applicationContext.getBeansWithAnnotation(NacosRefreshStaticField.class);
            for (Map.Entry<String, Object> mapEntry : refreshStaticFieldBeanMap.entrySet()) {
                String beanName = mapEntry.getKey();
                if (ObjectUtil.isEmpty(beanName)) {
                    continue;
                }

                String fullClassName = refreshStaticFieldBeanMap.get(beanName).toString().split("@")[0];
                Class<?> refreshStaticFieldClass;
                try {
                    refreshStaticFieldClass = Class.forName(fullClassName);
                } catch (ClassNotFoundException e) {
                    throw new ClassNotFoundException("监听nacos刷新当前静态类属性,未找到当前类",e);
                }
                NacosRefreshStaticField refreshStaticConfig = refreshStaticFieldClass.getAnnotation(NacosRefreshStaticField.class);
                if (Objects.nonNull(refreshStaticConfig) && refreshStaticConfig.configPrefix().equalsIgnoreCase(configPrefix)) {
                    curClazz.set(refreshStaticFieldClass);
                }
            }
            Class<?> aClass = curClazz.get();
            if (Objects.isNull(aClass)) {
                return;
            }

            // 利用反射动态更新 静态变量
            Field[] declaredFields = aClass.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                if (declaredField.getName().equalsIgnoreCase(configRealVal)) {
                    log.info("刷新当前配置 更新当前类[{}] 静态属性 [{}]",aClass.getSimpleName(),declaredField.getName());
                    declaredField.setAccessible(true);
                    declaredField.set(null,after);
                }
            }

        }

    }
}

CommonWebConfig

@Data
@Component
@ConfigurationProperties(prefix = "common")
@RefreshScope
public class CommonWebConfig {

    private String apiUrl;

}

使用

@Component
@NacosRefreshStaticField(configPrefix="common")
public class ExampleComponent {
    public static String apiUrl = SpringUtil.getBean(CommonWebConfig.class).getApiUrl();
}

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

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

相关文章

其它IO合集

其它IO合集 1. 缓冲流1.1 概述1.2 字节缓冲流构造方法效率测试 1.3 字符缓冲流构造方法特有方法 2. 转换流2.1 字符编码和字符集字符编码字符集 2.2 编码引出的问题2.3 InputStreamReader类构造方法指定编码读取 2.4 OutputStreamWriter类构造方法指定编码写出转换流理解图解 3…

Java开发从入门到精通(十):Java的面向对象编程OOP:抽象类

Java大数据开发和安全开发 &#xff08;一)Java的抽象类1.1 什么是抽象类?1.2 抽象类的注意事项、特点1.3 认识一下抽象类1.4 抽象类的场景和好处1.4.1 抽象类案例 1.5 抽象类的常见应用场景:模板方法设计模式1.5.1 模板方法设计模式作用1.5.1 模板方法设计模式的写法 &#x…

AI开发者急需看的大语言模型基本原理

在学习大语言模型的基本原理的时候&#xff0c;发现遇到了很多问题&#xff0c;比如一个个单词是怎么转换为向量的&#xff0c;是提前得到的还是训练过程中得到&#xff1f;Transformer的输出向量又是怎么转化为自然语言的&#xff1f;Finetune的时候不是只需要输入和输出吗&am…

百度驾驶证C++离线SDK V1.1 C#接入

百度驾驶证C离线SDK V1.1 C#接入 目录 说明 效果 项目 代码 下载 说明 自己根据SDK封装了动态库&#xff0c;然后C#调用。 SDK包结构 效果 项目 代码 using Newtonsoft.Json; using OpenCvSharp; using System; using System.Collections.Generic; using System.…

不用Linux也可以的强大文本处理方法

不用Linux也可以的强大文本处理方法 标题党了&#xff0c;其实是论VIM的使用。 做生物信息分析最合适的还是Linux操作系统&#xff0c;所以生信宝典在最开始就推出了Linux学习系列&#xff0c;由浅入深的讲述了Linux学习中的关键点。 主要文章列举如下&#xff1a; Linux学…

连续上榜|全息网御实力入选《中国网络安全行业全景图》

2024年4月12日&#xff0c;国内网络安全专业媒体安全牛正式发布第十一版《中国网络安全行业全景图》&#xff08;以下简称“全景图”&#xff09;。 本次全景图研究历时近4个月&#xff0c;共收到510家国内安全厂商4941项申报&#xff0c;实际收录2413项&#xff08;包含部分往…

Flutter 之 HTTP3/QUIC 和 Cronet 你了解过吗?

虽然 HTTP3/QUIC 和 cronet 跟 Flutter 没太大关系&#xff0c;只是最近在整理 Flutter 相关资料时发现还挺多人不了解&#xff0c;就放到一起聊聊。 本篇也是主要将现有资料做一些简化整合理解。 前言 其实为什么会有 HTTP3/QUIC &#xff1f;核心原因还是现有协议已经无法满…

van-uploader 在app内嵌的webview中的一些坑

问题&#xff1a; 部分版本在ios 中没有问题&#xff0c;但是安卓中不触发图片选择和拍照&#xff08;之前是可以的&#xff0c;可能是没有锁定版本&#xff0c;重新发版导致的&#xff09;。在ios中下拉文案是英文&#xff0c;html配置lang等于 zh 也没有用&#xff0c;ios里…

强化网络安全防线,您的等级保护措施到位了吗?

在这个信息化飞速发展的时代&#xff0c;网络安全已经成为我们每个人都需要关注的问题。无论是企业还是个人&#xff0c;我们的工作和生活都越来越依赖于网络。确保网络环境的安全&#xff0c;防止信息泄露和网络攻击&#xff0c;已经成为了一项至关重要的任务。等级保护制度作…

Oracle 正则,开窗,行列转换

1.开窗函数 基本上在查询结果上添加窗口列 1.1 聚合函数开窗 基本格式: ..... 函数() over([partition by 分组列,...][order by 排序列 desc|asc][定位框架]) 1&#xff0c;partition by 字段 相当于group by 字段 起到分组作用2&#xff0c;order by 字段 即根据某个字段…

​面试经典150题——对称二叉树

1. 题目描述 2. 题目分析与解析 2.1 思路一——递归 为了解决问题“检查一个二叉树是否是对称的”&#xff0c;我们需要判断树的左子树和右子树是否是彼此的镜像。这意味着树的左子树的左侧应该与右子树的右侧相同&#xff0c;左子树的右侧应该与右子树的左侧相同。 定义问题…

基于springboot实现人口老龄化社区服务与管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现人口老龄化社区服务与管理系统演示 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了人口老龄化社区服务与管理平台的开发全过程。通过分析人口老龄化社区服务与管理平台方面的不足&#xff…

Gitee和Git学习笔记

Gitee和Git指令 Gitee提交代码方法1 先将仓库clone到本地&#xff0c;修改后再push到 Gitee 的仓库方法2 本地初始化一个仓库&#xff0c;设置远程仓库地址后再做push 切换分支下载代码通过git clone克隆仓库通过下载 ZIP 的方式下载代码 Git提交指令 解决本地库同时关联GitHub…

货币保卫战,美联储降息预期推迟,油价飙升110美元,亚洲市场股债汇三杀,各国央行操作难度上升!

货币保卫激战 美联储降息预期一降再降&#xff0c;叠加中东局势变化带来避险需求飙升&#xff0c;美元连续第五天上涨之际&#xff0c;新兴市场再次打响“货币保卫战”&#xff0c;而更大的风险似乎仍未过去。亚洲市场普跌&#xff0c;日股跌近2%&#xff0c;韩国股指跌超2%&a…

【好书推荐6】《Excel函数与公式应用大全for Excel 365 Excel 2021》

【好书推荐6】《Excel函数与公式应用大全for Excel 365 & Excel 2021》 写在最前面《Excel函数与公式应用大全for Excel 365 & Excel 2021》关键点内容简介作者简介前言/序言目录 &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时光&…

新手怎么做好抖音小店?这六点是做店的根本,新手商家做店必读

大家好&#xff0c;我是电商花花。 只要我们开通抖音小店&#xff0c;且缴纳好类目保证金&#xff0c;就可以正常选品&#xff0c;上架商品进行售卖了。 如果你是刚开通抖音小店&#xff0c;想要做好抖音小店&#xff0c;下面这几点&#xff0c;一定要注意看。 一、开通精选联…

低版本Oracle客户端或者CMD连接Oracle 12c数据库报错ORA-1017 ORA-12560

exp test_user/test_user123456jgzh fileC:\jgzh.dmp owner(msagx) compressy; exp test_user/test_user123456jgzh fileD:\jgzh.dmp tables(msagx.C_CB_STUDENT,msagx.C_CB_SUBJECT) feedback10000 compressy;

残差网络理解

看了知乎的一篇关于残差网络的文章&#xff0c;https://zhuanlan.zhihu.com/p/72679537&#xff0c;我想发表一点我自己的看法&#xff01; 1.我对残差网络的理解 残差网络&#xff08;ResNet&#xff09;确实与传统的卷积神经网络&#xff08;CNN&#xff09;在结构上有所不同…

Qwen1.5大语言模型微调实践

在人工智能领域&#xff0c;大语言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09;的兴起和广泛应用&#xff0c;为自然语言处理&#xff08;NLP&#xff09;带来了前所未有的变革。Qwen1.5大语言模型作为其中的佼佼者&#xff0c;不仅拥有强大的语言生成和理…

冯诺依曼与进程【Linux】

文章目录 冯诺依曼体系结构&#xff08;从硬件的角度描述&#xff09;冯诺依曼体系结构&#xff08;从软件的角度描述&#xff09;操作系统&#xff08;软件&#xff09;理解管理系统调用和库函数进程查看进程的两种方式 通过系统调用获取进程的PID和PPID通过系统调用创建进程-…