Spring Boot 项目使用 spring.config.import 接入 Nacos 配置中心

0 阅读3分钟

前言

使用Spring boot 3.5.6、Spring cloud Alibaba 2025.0.0.0 版本,bootstrap不起效了,折腾了半天,版本回退到2023.0.1.0才搞定。猜测新版应该是换了新的连接方式,找下资料还真是,记录下~

一、教程目标

通过本文你可以掌握:

  • 什么是 spring.config.import
  • 为什么新版 Spring Boot / Spring Cloud 接入 Nacos 要用它
  • 如何在项目中正确配置 Nacos 配置中心
  • 如何设计 Data ID、Group、Profile
  • 如何验证配置是否生效
  • 如何排查常见问题

二、适用场景

本文适用于以下场景:

  • Spring Boot 3.x 项目
  • 使用 Nacos 作为配置中心
  • 希望在启动时从 Nacos 拉取远程配置
  • 使用新版 Spring 配置加载体系
  • 使用 application.yml + spring.config.import 的方式接入

三、先理解:什么是 spring.config.import

1. 它是干什么的

spring.config.import 是 Spring Boot 2.4+ 引入的配置导入机制。

它的作用是:

告诉 Spring Boot:除了本地 application.yml,还要去其他地方加载配置。

这个“其他地方”可以是:

  • 本地文件
  • classpath 文件
  • 配置目录
  • 第三方配置中心
  • Nacos

2. 为什么接入 Nacos 要用它

在新版本 Spring Boot / Spring Cloud 中,远程配置加载已经逐步统一到 Config Data API 中。
Nacos 也不再只是“配上连接地址就自动帮你拉配置”,而是需要显式告诉 Spring:

你要导入哪些远程配置

这个动作就是通过 spring.config.import 完成的。

例如:

spring:
  config:
    import:
      - nacos:demo-service.yaml

这表示:

  • 去 Nacos 中找 demo-service.yaml
  • 拉取它的内容
  • 加入到 Spring 的配置环境中

四、接入前准备

在开始前,你需要准备好以下内容。

1. 启动一个可用的 Nacos 服务

默认地址通常是:

http://127.0.0.1:8848/nacos

默认账号密码一般是:

  • 用户名:nacos
  • 密码:nacos

2. 明确你的应用名

例如:

spring:
  application:
    name: order-service

这个名称后续通常会作为 Data ID 的一部分。

3. 明确环境

例如:

spring:
  profiles:
    active: dev

这样就能区分:

  • 公共配置
  • 服务配置
  • 环境配置

五、引入依赖

下面给出 Maven 示例。

注意:实际版本号请以你项目的 Spring Boot / Spring Cloud / Spring Cloud Alibaba 兼容矩阵为准。
这里主要演示配置方式。

Maven 示例

<dependencies>
    <!-- Web,可选 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Nacos Config -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>

    <!-- Actuator,便于排查配置 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

如果你使用 BOM 管理版本,建议统一通过 dependencyManagement 管理,不要在每个依赖里单独写版本。

六、Nacos 中先准备配置

假设你的应用名是:

order-service

激活环境是:

dev

那么推荐在 Nacos 中准备两份配置:

1. 服务公共配置

  • Data ID:order-service.yaml
  • Group:DEFAULT_GROUP

内容示例:

app:
  name: order-service
  desc: 订单服务公共配置

custom:
  username: common-user
  timeout: 30

2. 开发环境配置

  • Data ID:order-service-dev.yaml
  • Group:DEFAULT_GROUP

内容示例:

custom:
  username: dev-user
  timeout: 60

server:
  port: 8081

3. 为什么要拆成两份

因为一般推荐的加载结构是:

  1. 公共配置
  2. 环境配置

后加载的环境配置可以覆盖前面的公共配置。
比如上面的 custom.username

  • 在 order-service.yaml 中是 common-user
  • 在 order-service-dev.yaml 中是 dev-user

最终生效的会是 dev-user

七、核心配置:application.yml 怎么写

这是最关键的一步。

完整示例

spring:
  application:
    name: order-service

  profiles:
    active: dev

  config:
    import:
      - optional:nacos:${spring.application.name}.yaml?group=DEFAULT_GROUP
      - optional:nacos:${spring.application.name}-${spring.profiles.active}.yaml?group=DEFAULT_GROUP

  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
      username: nacos
      password: nacos
      config:
        namespace: public

management:
  endpoints:
    web:
      exposure:
        include: env,configprops,health

八、逐项解释这段配置


1. spring.application.name

spring:
  application:
    name: order-service

表示应用名。
后续我们用它拼接 Data ID:

  • order-service.yaml
  • order-service-dev.yaml

2. spring.profiles.active

spring:
  profiles:
    active: dev

表示当前运行环境。
会用于导入环境专属配置。

3. spring.config.import

spring:
  config:
    import:
      - optional:nacos:${spring.application.name}.yaml?group=DEFAULT_GROUP
      - optional:nacos:${spring.application.name}-${spring.profiles.active}.yaml?group=DEFAULT_GROUP

这是关键。

第一行:

optional:nacos:${spring.application.name}.yaml?group=DEFAULT_GROUP

展开后等于:

optional:nacos:order-service.yaml?group=DEFAULT_GROUP

表示去 Nacos 导入服务公共配置。

第二行:

optional:nacos:${spring.application.name}-${spring.profiles.active}.yaml?group=DEFAULT_GROUP

展开后等于:

optional:nacos:order-service-dev.yaml?group=DEFAULT_GROUP

表示导入开发环境配置。

4. 什么是 optional:

optional: 表示这份配置如果不存在,不让应用启动失败。

例如:

optional:nacos:order-service-dev.yaml

如果 Nacos 中没有这份配置,应用仍可继续启动。

如果你不加 optional:

nacos:order-service-dev.yaml

那么配置不存在时,应用可能直接启动失败。

建议

  • 开发环境:可以使用 optional:
  • 生产环境:关键配置可不加 optional:,防止漏配

5. spring.cloud.nacos.server-addr

spring:
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848

表示 Nacos 地址。

6. username / password

spring:
  cloud:
    nacos:
      username: nacos
      password: nacos

如果 Nacos 开启鉴权,需要填写。

7. namespace

spring:
  cloud:
    nacos:
      config:
        namespace: public

表示从哪个命名空间读取配置。
如果你在 Nacos 中把配置发布在某个自定义 namespace 下,这里必须一致。

九、为什么不能只配 spring.cloud.nacos.config.*

很多人会问:

我不是已经配了 server-addrnamespace 吗,为什么还要写 spring.config.import

答案是:

  • spring.cloud.nacos.* 负责“怎么连接 Nacos”
  • spring.config.import 负责“要导入哪些配置”

可以理解为:

  • 前者是“连接参数”
  • 后者是“取数指令”

只有连接参数,没有导入声明,Spring Boot 在新体系下可能不会主动去加载远程配置。

十、启动项目并验证

1. 启动类示例

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

2. 创建读取配置的 Controller

package com.example.demo.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class ConfigTestController {

    @Value("${custom.username:default-user}")
    private String username;

    @Value("${custom.timeout:10}")
    private Integer timeout;

    @Value("${app.name:unknown}")
    private String appName;

    @Value("${app.desc:no-desc}")
    private String appDesc;

    @GetMapping("/config")
    public Map<String, Object> config() {
        Map<String, Object> map = new HashMap<>();
        map.put("username", username);
        map.put("timeout", timeout);
        map.put("appName", appName);
        map.put("appDesc", appDesc);
        return map;
    }
}

3. 启动后访问

访问:

http://localhost:8081/config

如果配置正常生效,你会看到类似结果:

{
  "username": "dev-user",
  "timeout": 60,
  "appName": "order-service",
  "appDesc": "订单服务公共配置"
}

这说明:

  • app.* 来自 order-service.yaml
  • custom.* 部分被 order-service-dev.yaml 覆盖

十一、推荐的配置组织方式

企业项目建议使用下面这种分层。

1. 公共基础配置

Data ID:

common.yaml

内容例如:

logging:
  level:
    root: info 

2. 服务配置

Data ID:

order-service.yaml

内容例如:

app:
  name: order-service

3. 环境配置

Data ID:

order-service-dev.yaml

内容例如:

server:
  port: 8081

4. application.yml 写法

spring:
  application:
    name: order-service

  profiles:
    active: dev

  config:
    import:
      - optional:nacos:common.yaml?group=DEFAULT_GROUP
      - optional:nacos:${spring.application.name}.yaml?group=DEFAULT_GROUP
      - optional:nacos:${spring.application.name}-${spring.profiles.active}.yaml?group=DEFAULT_GROUP

  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
      username: nacos
      password: nacos
      config:
        namespace: public

十二、配置优先级怎么理解

导入顺序通常建议按以下顺序写:

  1. 公共配置
  2. 服务配置
  3. 环境配置

后者覆盖前者。

例如:

spring:
  config:
    import:
      - optional:nacos:common.yaml
      - optional:nacos:order-service.yaml
      - optional:nacos:order-service-dev.yaml

如果三份配置都定义了:

custom.timeout

则通常最后导入的 order-service-dev.yaml 优先级更高。