Spring Cloud Alibaba 2025.0.0 配置中心踩坑日记

从 2021.x 升到 2025.0.0 之后,配置中心的写法全变了。bootstrap.yml 默认关掉、spring.config.import 接入方式也换了、Nacos Server 版本还不对齐。踩了一堆坑,整理下来备忘。


环境

组件 版本
Spring Boot 3.5.16
Spring Cloud 2025.0.0
Spring Cloud Alibaba 2025.0.0.0
Nacos Server 3.0.3
Java 17

坑:spring-cloud-starter-bootstrap 和 spring.config.import 不能共存

现象

加了 spring-cloud-starter-bootstrap 依赖,同时又在 application-dev.yml 里用 spring.config.import 导入 Nacos 配置。Nacos 控制台改了配置,服务端也收到了推送,但 @RefreshScope 的 Bean 不刷新。日志里永远是:

Refresh keys changed: []

涉及的依赖

先说清楚这里涉及哪几个包:

<!-- 这个必须引入,Nacos 配置中心的核心包 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

<!-- 这个可选,作用是重新打开 Spring Cloud 默认关闭的 bootstrap 上下文 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>

spring-cloud-starter-alibaba-nacos-config 这个包内部带了两套加载机制:

  • NacosPropertySourceLocator——走 bootstrap 阶段加载配置。需要 spring-cloud-starter-bootstrap 打开 bootstrap 上下文才会触发
  • NacosConfigDataLoader——走 spring.config.import 阶段加载配置。不需要 bootstrap,Spring Cloud 2025 默认方式

如果你同时引入上面两个依赖,又在 application-dev.yml 里配了 spring.config.import,两套机制会一起跑

原因

两套机制一起跑,Nacos 配置被加载了两次:

pom.xml 里引入了

触发

无需 bootstrap

拉配置

又拉一次

ContextRefresher 刷新这一份

@ConfigurationProperties 绑的是这一份

spring-cloud-starter-bootstrap
(打开了 bootstrap 上下文)

spring-cloud-starter-alibaba-nacos-config
(自带两套加载器)

bootstrap 阶段
NacosPropertySourceLocator

spring.config.import 阶段
NacosConfigDataLoader

Nacos Server

PropertySource A
挂到 Environment

PropertySource B
又挂到 Environment

刷新事件

Bean 绑定

Nacos 推送配置变更时:

  • NacosContextRefresher → 刷新 PropertySource A → A 的值确实变了
  • 但你的 @ConfigurationProperties Bean → 绑的是 PropertySource B → B 没变
  • ContextRefresher 对比新旧值 → 穿帮了 → 检测不到变化 → Refresh keys changed: []

两条链路各玩各的,刷新了个寂寞。

解决

二选一,只留一条路。

方案 A:只用 spring.config.import(推荐)

删掉 spring-cloud-starter-bootstrap

<!-- ❌ 删掉 -->
<!-- <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency> -->

<!-- ✅ 只留这一个 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

application-dev.yml——不要有 bootstrap.yml

spring:
  config:
    import:
      - optional:nacos:idle-store-oss-dev.yaml?group=DEFAULT_GROUP&refreshEnabled=true
  cloud:
    nacos:
      config:
        group: DEFAULT_GROUP
        server-addr: 127.0.0.1:8848
        namespace: idlestore
      discovery:
        enabled: true
        group: DEFAULT_GROUP
        namespace: idlestore
        server-addr: 127.0.0.1:8848

方案 B:只用 bootstrap.yml(老项目过渡用,2025.1.x 之后废弃)

保留两个依赖:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>

bootstrap.yml

spring:
  application:
    name: idle-store-auth
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        namespace: idlestore
        file-extension: yaml
        refresh-enabled: true
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: idlestore

application-dev.yml——不要写 spring.config.import

spring:
  application:
    name: idle-store-auth

2025.0.0 的正确打开方式

踩完上面的坑,总结一套能跑的配置模板。

父 pom

<properties>
    <java.version>17</java.version>
    <spring-boot.version>3.5.16</spring-boot.version>
    <spring-cloud.version>2025.0.0</spring-cloud.version>
    <spring-cloud-alibaba.version>2025.0.0.0</spring-cloud-alibaba.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>${spring-cloud-alibaba.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

子模块依赖

<!-- Nacos 配置中心 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

<!-- Nacos 服务发现 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<!-- 不要引入 spring-cloud-starter-bootstrap! -->

配置文件(推荐 spring.config.import 方式)

# application-dev.yml
spring:
  application:
    name: your-service-name
  config:
    import:
      - optional:nacos:your-service-name-dev.yaml?group=DEFAULT_GROUP&refreshEnabled=true  # 这个前面对应的是 nacos 的 data-id
  cloud:
    nacos:
      config:
        group: DEFAULT_GROUP
        server-addr: 127.0.0.1:8848
        namespace: your-namespace
      discovery:
        enabled: true
        group: DEFAULT_GROUP
        namespace: your-namespace
        server-addr: 127.0.0.1:8848
# Nacos 里的 your-service-name-dev.yaml —— 放需要动态刷新的业务配置
your-property: your-value

代码里绑定配置

@ConfigurationProperties("storage")
@Component
@RefreshScope   // 别忘了
@Data
public class StorageProperties {
    private String type;
}
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐