bigywater.tech
Spring · 10

@Conditional 系列与 Profile

@Profile 到底怎么选?默认 profile 什么时候失效?自定义 @Conditional 为什么会随配置类顺序变化?类上和方法上的条件有什么区别?这篇在 Spring Framework 7.0.9 上把条件装配的几个坑逐个跑出来。

default
没有激活任何 profile 时的默认 profile;激活别的 profile 后它就不再生效
2 种
同样的“没有 dataSource 才注册”,在不同注册顺序下得到 [dataSource] 与 [dataSource, fallbackDs]
[keep]
类上和方法上的 @Conditional(false) 之后,容器里剩下的 Bean

Profile

实测 · 本机执行输出
  什么都不激活:激活 [],默认 [default] → [always, notProd, onlyDefault]
  setActiveProfiles(dev):激活 [dev],默认 [default] → [always, dev, devNotCloud, notProd]
  setActiveProfiles(prod):激活 [prod],默认 [default] → [always, prod, prodOrCloud]
  setActiveProfiles(dev, cloud):激活 [dev, cloud],默认 [default] → [always, dev, notProd, prodOrCloud]
  -Dspring.profiles.active=dev:激活 [dev],默认 [default] → [always, dev, devNotCloud, notProd]
  setDefaultProfiles(base),没有激活:激活 [],默认 [base] → [always, notProd]

没有激活时用 default;激活了别的 profile,default 就不再生效;支持 &、|、! 表达式。

条件与顺序

实测 · 本机执行输出
  注册顺序 [User, FallbackBean] → [dataSource]
      · MissingDs(REGISTER_BEAN 阶段)被求值:registry 里已有 dataSource = true
  注册顺序 [FallbackBean, User] → [dataSource, fallbackDs]
      · MissingDs(REGISTER_BEAN 阶段)被求值:registry 里已有 dataSource = false

“缺失才注册”类的条件依赖配置类的注册顺序。

求值阶段

实测 · 本机执行输出
  注册顺序 [User, FallbackParse] → [dataSource, fallbackDsParse]
      · MissingDsParse(PARSE_CONFIGURATION 阶段)被求值:registry 里已有 dataSource = false
      · MissingDsParse(PARSE_CONFIGURATION 阶段)被求值:registry 里已有 dataSource = false
  注册顺序 [FallbackParse, User] → [dataSource, fallbackDsParse]
      · MissingDsParse(PARSE_CONFIGURATION 阶段)被求值:registry 里已有 dataSource = false
      · MissingDsParse(PARSE_CONFIGURATION 阶段)被求值:registry 里已有 dataSource = false

类上的 ConfigurationCondition 在解析阶段求值,看不到 @Bean 方法注册的定义。

类上与方法上

实测 · 本机执行输出
  类上 @Conditional(false)、方法上 @Conditional(false) 之后剩下 → [keep]

类上的 @Conditional 一次跳过整个类及其 @Import 与嵌套配置类。

分步演示

条件装配与 Profile
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK 21.0.12(Homebrew) / Spring Boot 4.0.8(Spring Framework 7.0.9、Tomcat 11.0.24) / Spring Cloud 2025.1.3;用 javac 编译、java 直接运行,依赖由 Maven 从 Maven Central 解析;数字每次运行会有小幅抖动。用不带 Boot 的 Spring Framework 7.0.9 的 AnnotationConfigApplicationContext(Boot 的 @ConditionalOnMissingBean 等在后面的 Boot 篇讲);第一节的 -Dspring.profiles.active 是通过 JVM 系统属性传的
    • 没有验证:Boot 的 spring.profiles.active 在配置文件、环境变量里的优先级(见 Boot 篇);@Profile 放在 @Component 类上的效果;自定义条件读取 Environment 属性;@ConditionalOnMissingBean 在 Boot 自动配置里怎样靠 @AutoConfiguration 的排序解决顺序问题(见 Boot 篇);条件求值的耗时
    京ICP备2026067502号-1京公网安备11010502063487号