Spring 中使用Nacos服务发现

news2025/7/7 14:18:33

引入依赖

<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-spring-context</artifactId>
    <version>${latest.version}</version>
</dependency>

本文使用的版本为:1.1.1(与Spring 中使用Nacos配置管理一章引用的依赖一样)

示例

package com.yyoo.nacos.spring.discovery;

import com.alibaba.nacos.api.annotation.NacosProperties;
import com.alibaba.nacos.spring.context.annotation.discovery.EnableNacosDiscovery;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableNacosDiscovery(globalProperties = @NacosProperties(serverAddr = "127.0.0.1:8848"))
public class DiscoveryConfiguration {
}
package com.yyoo.nacos.spring.discovery;

import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
@RequestMapping("discovery")
public class DiscoveryController {

    @NacosInjected
    private NamingService namingService;

    @RequestMapping(value = "/register", method = RequestMethod.GET)
    @ResponseBody
    public void register(@RequestParam String serviceName) throws NacosException {
        namingService.registerInstance(serviceName,"111.111.1.1",8888);
    }


    @RequestMapping(value = "/get", method = RequestMethod.GET)
    @ResponseBody
    public List<Instance> get(@RequestParam String serviceName) throws NacosException {
        return namingService.getAllInstances(serviceName);
    }
}
    @Test
    public void testSpring3() throws NacosException {

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.scan("com.yyoo");
        context.refresh();

        String serviceName = "testDiscovery";
        DiscoveryController controller = context.getBean(DiscoveryController.class);
        controller.register(serviceName);
        System.out.println(controller.get(serviceName));

    }

注:此处是为了方便,模拟请求Controller,其实效果是一样的。

目前还未注册服务,所以打印结果为:

[Instance{instanceId=‘111.111.1.1#8888#DEFAULT#DEFAULT_GROUP@@testDiscovery’, ip=‘111.111.1.1’, port=8888, weight=1.0, healthy=true, enabled=true, ephemeral=true, clusterName=‘DEFAULT’, serviceName=‘DEFAULT_GROUP@@testDiscovery’, metadata={}}]

此时可以查看Nacos服务管理界面
在这里插入图片描述

@NacosInjected注解详解

@NacosInjected 是一个核心注解,用于在Spring Beans 中注入 ConfigService 或 NamingService 实例,并使这些实例可缓存

package com.yyoo.nacos.spring.discovery;

import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.annotation.NacosProperties;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.naming.NamingService;
import org.springframework.stereotype.Component;

@Component
public class InjectedBean {

    @NacosInjected
    private ConfigService configService;

    @NacosInjected(properties = @NacosProperties(encode = "UTF-8"))
    private ConfigService configService2;

    @NacosInjected(properties = @NacosProperties(encode = "GBK"))
    private ConfigService configService3;

    @NacosInjected
    private NamingService namingService;

    @NacosInjected(properties = @NacosProperties(encode = "UTF-8"))
    private NamingService namingService2;

    @NacosInjected(properties = @NacosProperties(encode = "GBK"))
    private NamingService namingService3;


    public void testInjection() {

        System.out.println("configService == configService2:" + (configService == configService2));
        System.out.println("configService2 == configService3:" + (configService2 == configService3));

        System.out.println("namingService == namingService2:" + (namingService == namingService2));
        System.out.println("namingService2 == namingService3:" + (namingService2 == namingService3));
    }

}

结果:
configService == configService2:true
configService2 == configService3:false
namingService == namingService2:true
namingService2 == namingService3:false

结论: @NacosProperties 相等,则实例将是相同的,无论属性是来自全局还是自定义的 Nacos 属性。反之,如果@NacosProperties不相等,实例不是相同的,建议在同一个应用内使用相同的配置。

配置监听注解

package com.yyoo.nacos.spring.bean;

import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.annotation.NacosConfigListener;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ConfigBean {

    @NacosInjected
    private ConfigService configService;

    @NacosConfigListener(dataId = "com.yyoo.nacos.sdk.CofingServiceTest",groupId = "Nacos:Test")
    public void onMessage(String config) {
        System.out.println("listener:"+config);
    }

}
    @NacosConfigListener(dataId = "com.yyoo.nacos.sdk.CofingServiceTest",groupId = "Nacos:Test")
    public void onMessage(String config) {
        System.out.println("listener:"+config);
    }

以上代码等价于:

configService.addListener("com.yyoo.nacos.sdk.CofingServiceTest", "Nacos:Test", new AbstractListener() {
    @Override
    public void receiveConfigInfo(String config) {
        System.out.println("listener:"+config);
    }
});

为监听添加类型转换器

@NacosConfigListener 的类型转换包括内置和自定义实现。 默认情况下,内置类型转换基于 Spring DefaultFormattingConversionService来实现。常见的基本类型都可以自动转换。
比如我们上面示例的DataId:“com.yyoo.nacos.sdk.CofingServiceTest”,groupId:“Nacos:Test”

在这里插入图片描述

其是一个Json类型,我们监听示例中使用String类型是可以的。如果我们需要将其在监听中解析成对象呢?这个时候就需要类型转换器了,自定义实现NacosConfigConverter接口即可自己实现类型转换器,比如我们自定义实现上面JSON配置内容的类型转换器

package com.yyoo.nacos.spring.bean;

import com.alibaba.nacos.api.config.convert.NacosConfigConverter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;


public class TestNacosConfigConverter implements NacosConfigConverter<TestNacosConfig> {

    @Override
    public boolean canConvert(Class<TestNacosConfig> targetType) {
        return true;
    }

    @Override
    public TestNacosConfig convert(String config) {
        ObjectMapper mapper = new ObjectMapper();
        TestNacosConfig obj = null;
        try {
            obj =  mapper.readValue(config,TestNacosConfig.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return obj;
    }
}

编写自定义对象

package com.yyoo.nacos.spring.bean;

public class TestNacosConfig {
    private String conf1;
    private String conf2;

    public String getConf1() {
        return conf1;
    }

    public void setConf1(String conf1) {
        this.conf1 = conf1;
    }

    public String getConf2() {
        return conf2;
    }

    public void setConf2(String conf2) {
        this.conf2 = conf2;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("TestNacosConfig{");
        sb.append("conf1='").append(conf1).append('\'');
        sb.append(", conf2='").append(conf2).append('\'');
        sb.append('}');
        return sb.toString();
    }
}

修改添加监听的程序

    @NacosConfigListener(dataId = "com.yyoo.nacos.sdk.CofingServiceTest",groupId = "Nacos:Test",converter = TestNacosConfigConverter.class)
    public void onMessage(TestNacosConfig config) {
        System.out.println("bean listener:"+config);
    }

测试代码:

    @Test
    public void testSpring5() throws NacosException, InterruptedException {

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.scan("com.yyoo");
        context.refresh();

        Thread.sleep(60000); // 休眠60秒,保证主程序不关闭

    }

测试代码主程序没有停止前,在Nacos配置界面修改对应的配置conf2=‘test2’,监听程序打印结果:

bean listener:TestNacosConfig{conf1=‘test1’, conf2=‘test2’}

监听超时时间设置

由于运行自定义的 NacosConfigConverter 可能需要一些时间,因此您可以在 @NacosConfigListener.timeout() 属性中设置最大执行时间,以防止它阻塞其他侦听器。只需在@NacosConfigListener注解上加上timeout属性配置即可,timeout默认为1000L

    @NacosConfigListener(dataId = "com.yyoo.nacos.sdk.CofingServiceTest",groupId = "Nacos:Test"
            ,converter = TestNacosConfigConverter.class,timeout = 1000L)
    public void onMessage(TestNacosConfig config) {
        System.out.println("bean listener:"+config);
    }

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

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

相关文章

微服务(二)——注册中心(Eureka、Nacos)

目录1. 概念2. Eureka1. 服务搭建1. 依赖导入2. 配置文件3. 启动项目2. 服务注册1. 依赖导入2. 配置文件3. 启动多个实例3. 服务发现1. 依赖导入2. 配置文件3. 服务拉取和负载均衡4. 小结3. Ribbon1. 负载均衡流程2. 负载均衡策略3. 加载策略4. Nacos1. 下载安装2. 注册中心1. …

css:隐藏input file标签并触发点击上传文件事件

目录方式一&#xff1a;将input标签覆盖到按钮的最上层方式二&#xff1a;通过label标签触发点击事件方式三&#xff1a;js触发文件上传的点击事件总结通用的按钮样式 /* button样式来自element-ui */ .button {color: #fff;background-color: #409eff;display: inline-block;…

【MQTT】mqtt + go + M5Stack + SSR 远程灯控程序

1. mqtt服务搭建 参考上一篇文章【MQTT】mqtt 服务器部署--go 生产和消费demo_平静不绝望的博客-CSDN博客 2. M5stack 烧录和编程 详细文档&#xff1a;m5-docs mac 需要安装USB驱动 和 m5burner 如下图 3. flow ui 编程 SSR 4. go web远程代码 s.Router.HandleFunc(&…

UE中的FString操作

此篇是指单纯记录&#xff0c;方便之后查阅。 目录 创建 转型到FString FString转型到其他类型 字符串中是否包含指定串 查找给定串在其中是什么位置 字符串比较 读文件 裁剪字符串 编码解决的是文字问题 稍微细致一些的可以看&#xff1a; UE4随笔&#xff1a;FStri…

TI 2640 Quick start

&#xff08;1&#xff09;下载ccs 并且安装 &#xff08;2&#xff09;下载对应版本的SDK&#xff0c;并且安装 SDK对应版本下载可以通过搜索的方式&#xff1a;simplelink_cc2640r2_sdk_5_30_00_03 &#xff08;3&#xff09;导入对应的工程文件 此篇文档可以作为参考&#x…

喜讯丨计讯物联荣获厦门软件园党群服务中心篮球赛亚军

蓄势待发迎“篮”上&#xff0c;齐心协力谱新篇。12月17日&#xff0c;厦门软件园党群服务中心篮球赛完美落幕。计讯物联一路过关斩将&#xff0c;荣获厦门软件园党群服务中心篮球赛亚军。 决胜雅马哈&#xff0c;强势晋级半决赛 随着一声哨响&#xff0c;比赛正式拉开帷幕&…

2个月备考通过系统架构设计师考试,把经验分享给孤军奋战的你

一、前言 本来于2022-08-29报考系统架构设计师&#xff0c;报考完成以后才开始了正式的学习&#xff0c;也就是9月初才开始系统学习&#xff0c;2022-11-05开始考试&#xff0c;中间准备了两个月的时间。 当时公司业务受疫情影响严重&#xff0c;领导叫我考一个证书吧&#xf…

Android制作简易的音乐播放器和视频播放器

文章目录制作简易的音乐播放器和视频播放器播放多媒体文件播放音频MediaPlayer的工作流程项目示例播放视频项目示例制作简易的音乐播放器和视频播放器 播放多媒体文件 Android在播放音频和视频方面做了非常不错的支持,它提供了一套非常完整的API,使得开发者可以轻松编写出一个…

JavaEE入门知识

1.为什么要学习框架&#xff1f; 1. 学习框架相当于从“⼩作坊”到“⼯⼚”的升级&#xff0c;⼩作坊什么都要⾃⼰做&#xff0c;⼯⼚是组件式装配&#xff0c;特点就是⾼效。 2. 框架更加易⽤、简单且⾼效。 2.创建一个Servlet项目&#xff08;我使用的是IDEA专业版&#…

USB TO SPI(上海同旺电子)调试器调试MCP6S92

所需设备&#xff1a; 1、USB TO SPI(上海同旺电子)&#xff1b; 2、MCP6S92 单端轨到轨输入/ 输出低增益PGA; 特性 • 复用输入&#xff1a;1 或2 个通道 • 8 种增益选择&#xff1a; - 1、2、4、5、8、10、16 或32 V/V • 串行外设接口&#xff08;SPI&#xff09; • 轨…

生成模型(三):基于流的生成模型(Flow-based model)

本文大纲如下&#xff1a; 到目前为止&#xff0c;已经介绍了[[生成模型-GAN]]和[[生成模型-VAE]]。它们都没有明确地学习真实数据的概率密度函数p(\mathbf{x})&#xff08;其中\mathbf{x}\in \mathcal{D}&#xff09;, 因为很难。以带有潜变量的生成模型为例&#xff0c;p(\ma…

Web前端105天day61-HTML5_CORE

HTML5CORE01 目录 前言 一、拖拽上传文件 1.1.文件上传 二、跨域 三、跨域解决方案 四、查看网站接口 五、文件上传服务 总结 前言 HTML5CORE01学习开始 HTML5 : 目前主流的 HTML 版本, 其中增加了很多新特性例如: 音视频, 网页存储技术 - webStorage一、拖拽上传文件…

TensorRT学习笔记 1 - 概述

TensorRT系列笔记是作者半年来学习和使用TensorRT(后称trt)积累笔记 整理和心得。包含trt的基本概念&#xff0c;相关资料&#xff0c;实践笔记&#xff0c;踩坑记录等等。 本篇博客希望可以初步说清楚 trt是什么&#xff1b;模型部署为什么使用trt&#xff0c;以及使用trt的…

渗透攻击MS08-067

学校课程关于Metasploit有基础的几个小实验&#xff0c;把它整理分享在这里。 实训目的&#xff1a; 熟悉Metasploit终端的使用方法&#xff0c;了解MS08-067漏洞&#xff0c;掌握对MS08-067漏洞攻击的方法。 场景描述&#xff1a; 在虚拟机环境下配置 “WinXP1”和“Kali …

华为机试_HJ63 DNA序列【中等】

目录 描述 输入描述&#xff1a; 输出描述&#xff1a; 解题过程 提交代码 学习代码 代码一 收藏点 描述 一个 DNA 序列由 A/C/G/T 四个字母的排列组合组成。 G 和 C 的比例&#xff08;定义为 GC-Ratio &#xff09;是序列中 G 和 C 两个字母的总的出现次数除以总的字…

公开竞价与封闭式竞价有什么不同?

电子竞价是电子采购的一种形式。电子采购是指通过信息和网络系统在线进行的招标采购过程。 电子竞价是指一种基于网络的系统&#xff0c;允许潜在供应商在网上实时竞争商品/服务的价格。电子竞价的使用方式类似于e-bay平台&#xff0c;出价最高者获胜。在建筑业&#xff0c;这…

前端_Vue_7.表单输入绑定

文章目录一、 表单输入绑定1.0. 表单&表单元素1.0.1. 表单1.0.2. 表单元素1.1. 基本用法1.1.1. 文本1.1.2. 多行文本1.1.3. 复选框1.1.4. 单选按钮1.1.5. 选择器1.2. 值绑定1.2.1. 复选框1.2.2. 单选按钮1.2.3. 选择器选项1.3. 修饰符1.3.1. .lazy1.3.2. .number1.3.3. .tr…

三角函数公式

三角函数的定义 锐角三角函数任意角三角函数正弦sin⁡Aac\sin A\dfrac acsinAca​sin⁡θyr\sin \theta\dfrac yrsinθry​余弦cos⁡Abc\cos A\dfrac bccosAcb​cos⁡θxr\cos \theta\dfrac xrcosθrx​正切tan⁡Aab\tan A\dfrac abtanAba​tan⁡θyx\tan \theta\dfrac yxtanθ…

mysql中常用命令完整大全 适用于mysql8.0

关于安装部分就去看其他人的一些文章即可网上太多&#xff0c;这篇文章主要就是记录本人的一些关于mysql操作上的笔记。 mysql中常用命令1.登录数据库2.查看当前数据库3.创建数据库4.删除数据库5.创建表user基于以下条件6.使用主键约束7.指定非空8.唯一约束9.默认约束10.设置表…

物联网时代下的5G融合定位,可以实现哪些功能?

5G具有高带宽、高频谱&#xff08;毫米波&#xff09;、多天线阵列等特性&#xff0c;通过提升无线定位算法的能力、室内数字系统建设、完善5G定位服务流程以及与其它定位技术和平台的结合&#xff0c;可提高5G定位精度。室内高精度定位服务为5G定位扩展到更多应用场景和领域构…