bigywater.tech
Spring · 65

自动配置:AutoConfiguration.imports 与 @Conditional 的求值

自动配置到底是怎么被加载的?为什么我的 @ConditionalOnBean 没生效?after 和 before 有什么用?没列在 imports 里会怎样?怎么看到每个条件为什么失败?这篇自己写了 5 个自动配置类,在 Spring Boot 4.0.8 上逐个验证。

5 / 24
Boot 自带的 *AutoConfiguration 在条件报告里出现 24 个,条件全部满足生效的只有 5 个(webmvc 类路径、非 Web 模式)
0
没列在 imports 里的 @AutoConfiguration 类的 Bean 个数——既没导入也没被扫描
77 → 73
greeting.enabled=false 时 Bean 总数的变化

默认

实测 · 本机执行输出
  afterMarker              存在
  tooEarlyMarker           不存在
  ghostMarker              不存在
  unlistedMarker           不存在
  userDependsOnGreeter     不存在
  user2DependsOnGreeter    不存在
  Greeter 类型的 Bean = [defaultGreeter],greet() = [default greeter(来自自动配置)]
  --- 自己写的几个配置类在条件报告里的结果 ---
  UserConfig#userDependsOnGreeter → 不匹配
        ✗ OnBeanCondition: @ConditionalOnBean (types: demo.lib.Greeter; SearchStrategy: all) did not find any beans of type demo.lib.Greeter
  UserConfig#userGreeter → 不匹配
        ✗ OnPropertyCondition: @ConditionalOnProperty (user.greeter) did not find property 'user.greeter'
  UserConfig2 → 不匹配
        ✗ OnPropertyCondition: @ConditionalOnProperty (user.greeter) did not find property 'user.greeter'
  lib.DecoratorAutoConfiguration → 匹配
        ✓ OnBeanCondition: @ConditionalOnBean (types: demo.lib.Greeter; SearchStrategy: all) found bean 'defaultGreeter'
  lib.GhostAutoConfiguration → 不匹配
        ✗ OnClassCondition: @ConditionalOnClass did not find required class 'com.nowhere.Missing'
  lib.GreetingAutoConfiguration → 匹配
        ✓ OnClassCondition: @ConditionalOnClass found required class 'demo.lib.Greeter'
        ✓ OnPropertyCondition: @ConditionalOnProperty (greeting.enabled=true) matched
  lib.GreetingAutoConfiguration#defaultGreeter → 匹配
        ✓ OnBeanCondition: @ConditionalOnMissingBean (types: demo.lib.Greeter; SearchStrategy: all) did not find any beans
  lib.TooEarlyAutoConfiguration → 不匹配
        ✗ OnBeanCondition: @ConditionalOnBean (types: demo.lib.Greeter; SearchStrategy: all) did not find any beans of type demo.lib.Greeter
  Boot 自带的 *AutoConfiguration 在条件报告里出现 24 个,其中条件全部满足(生效)的 5 个;spring.autoconfigure.exclude 排除掉的 = []
  Bean 总数 = 77

imports 里列的才导入;after / before 决定 @ConditionalOnBean 能否看到对方的 Bean。

属性开关

实测 · 本机执行输出
  afterMarker              不存在
  tooEarlyMarker           不存在
  ghostMarker              不存在
  unlistedMarker           不存在
  userDependsOnGreeter     不存在
  user2DependsOnGreeter    不存在
  Greeter 类型的 Bean = [],greet() = []
  --- 自己写的几个配置类在条件报告里的结果 ---
  UserConfig#userDependsOnGreeter → 不匹配
        ✗ OnBeanCondition: @ConditionalOnBean (types: demo.lib.Greeter; SearchStrategy: all) did not find any beans of type demo.lib.Greeter
  UserConfig#userGreeter → 不匹配
        ✗ OnPropertyCondition: @ConditionalOnProperty (user.greeter) did not find property 'user.greeter'
  UserConfig2 → 不匹配
        ✗ OnPropertyCondition: @ConditionalOnProperty (user.greeter) did not find property 'user.greeter'
  lib.DecoratorAutoConfiguration → 不匹配
        ✗ OnBeanCondition: @ConditionalOnBean (types: demo.lib.Greeter; SearchStrategy: all) did not find any beans of type demo.lib.Greeter
  lib.GhostAutoConfiguration → 不匹配
        ✗ OnClassCondition: @ConditionalOnClass did not find required class 'com.nowhere.Missing'
  lib.GreetingAutoConfiguration → 不匹配
        ✓ OnClassCondition: @ConditionalOnClass found required class 'demo.lib.Greeter'
        ✗ OnPropertyCondition: @ConditionalOnProperty (greeting.enabled=true) found different value in property 'enabled'
  lib.TooEarlyAutoConfiguration → 不匹配
        ✗ OnBeanCondition: @ConditionalOnBean (types: demo.lib.Greeter; SearchStrategy: all) did not find any beans of type demo.lib.Greeter
  Boot 自带的 *AutoConfiguration 在条件报告里出现 24 个,其中条件全部满足(生效)的 5 个;spring.autoconfigure.exclude 排除掉的 = []
  Bean 总数 = 73

一个条件失败连带依赖它的配置。

用户覆盖

实测 · 本机执行输出
  afterMarker              存在
  tooEarlyMarker           存在
  ghostMarker              不存在
  unlistedMarker           不存在
  userDependsOnGreeter     不存在
  user2DependsOnGreeter    存在
  Greeter 类型的 Bean = [userGreeter],greet() = [user greeter(用户自己定义)]
  --- 自己写的几个配置类在条件报告里的结果 ---
  UserConfig#userDependsOnGreeter → 不匹配
        ✗ OnBeanCondition: @ConditionalOnBean (types: demo.lib.Greeter; SearchStrategy: all) did not find any beans of type demo.lib.Greeter
  UserConfig#userGreeter → 匹配
        ✓ OnPropertyCondition: @ConditionalOnProperty (user.greeter) matched
  UserConfig2 → 匹配
        ✓ OnPropertyCondition: @ConditionalOnProperty (user.greeter) matched
  UserConfig2#user2DependsOnGreeter → 匹配
        ✓ OnBeanCondition: @ConditionalOnBean (types: demo.lib.Greeter; SearchStrategy: all) found bean 'userGreeter'
  lib.DecoratorAutoConfiguration → 匹配
        ✓ OnBeanCondition: @ConditionalOnBean (types: demo.lib.Greeter; SearchStrategy: all) found bean 'userGreeter'
  lib.GhostAutoConfiguration → 不匹配
        ✗ OnClassCondition: @ConditionalOnClass did not find required class 'com.nowhere.Missing'
  lib.GreetingAutoConfiguration → 匹配
        ✓ OnClassCondition: @ConditionalOnClass found required class 'demo.lib.Greeter'
        ✓ OnPropertyCondition: @ConditionalOnProperty (greeting.enabled=true) matched
  lib.GreetingAutoConfiguration#defaultGreeter → 不匹配
        ✗ OnBeanCondition: @ConditionalOnMissingBean (types: demo.lib.Greeter; SearchStrategy: all) found beans of type 'demo.lib.Greeter' userGreeter
  lib.TooEarlyAutoConfiguration → 匹配
        ✓ OnBeanCondition: @ConditionalOnBean (types: demo.lib.Greeter; SearchStrategy: all) found bean 'userGreeter'
  Boot 自带的 *AutoConfiguration 在条件报告里出现 24 个,其中条件全部满足(生效)的 5 个;spring.autoconfigure.exclude 排除掉的 = []
  Bean 总数 = 81

@ConditionalOnMissingBean 让路;用户 Bean 在先也改变了别的配置的评估结果。

排除

实测 · 本机执行输出
  afterMarker              不存在
  tooEarlyMarker           不存在
  ghostMarker              不存在
  unlistedMarker           不存在
  userDependsOnGreeter     不存在
  user2DependsOnGreeter    不存在
  Greeter 类型的 Bean = [],greet() = []
  --- 自己写的几个配置类在条件报告里的结果 ---
  UserConfig#userDependsOnGreeter → 不匹配
        ✗ OnBeanCondition: @ConditionalOnBean (types: demo.lib.Greeter; SearchStrategy: all) did not find any beans of type demo.lib.Greeter
  UserConfig#userGreeter → 不匹配
        ✗ OnPropertyCondition: @ConditionalOnProperty (user.greeter) did not find property 'user.greeter'
  UserConfig2 → 不匹配
        ✗ OnPropertyCondition: @ConditionalOnProperty (user.greeter) did not find property 'user.greeter'
  lib.DecoratorAutoConfiguration → 不匹配
        ✗ OnBeanCondition: @ConditionalOnBean (types: demo.lib.Greeter; SearchStrategy: all) did not find any beans of type demo.lib.Greeter
  lib.GhostAutoConfiguration → 不匹配
        ✗ OnClassCondition: @ConditionalOnClass did not find required class 'com.nowhere.Missing'
  lib.TooEarlyAutoConfiguration → 不匹配
        ✗ OnBeanCondition: @ConditionalOnBean (types: demo.lib.Greeter; SearchStrategy: all) did not find any beans of type demo.lib.Greeter
  Boot 自带的 *AutoConfiguration 在条件报告里出现 24 个,其中条件全部满足(生效)的 5 个;spring.autoconfigure.exclude 排除掉的 = [demo.lib.GreetingAutoConfiguration]
  Bean 总数 = 73

spring.autoconfigure.exclude 按类名在评估前排除。

分步演示

自动配置
本步的对象

    本文用到的工具与边界

    • 本机 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 解析;数字每次运行会有小幅抖动。用 Spring Boot 4.0.8(spring-boot-starter-webmvc 类路径,非 Web 模式)的单个程序,自己写的自动配置放在同一个编译输出目录并写了 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports;条件结果取自 ConditionEvaluationReport;组件扫描不加载 @AutoConfiguration 类的原因取自对 spring-boot-autoconfigure 4.0.8 源码 AutoConfigurationExcludeFilter 的阅读,没有单独做对照实验
    • 没有验证:把 @AutoConfiguration 类放进组件扫描之外的包的差别;@AutoConfigureOrder 的作用;ConditionalOnSingleCandidate / OnWebApplication 等其他条件;旧的 spring.factories 注册方式在 Boot 4 里是否还生效;Boot 自带自动配置里条件失败的具体原因分布
    京ICP备2026067502号-1京公网安备11010502063487号