@EnableAutoConfiguration 通过导入 AutoConfigurationImportSelector 触发自动配置,后者扫描 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(2.7+)或 spring.factories 加载条件化配置类。

自动配置从哪里开始:@EnableAutoConfiguration 怎么触发的
Spring Boot 的自动配置不是凭空发生的,@EnableAutoConfiguration 是入口开关,但它本身不干活——它只是导入了 AutoConfigurationImportSelector。这个类在 Spring 容器刷新早期(ConfigurationClassPostProcessor 阶段)被调用,去扫描并加载所有符合条件的自动配置类。
关键点在于:它不读 @Configuration 类,而是读 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(Spring Boot 2.7+)或旧版的 META-INF/spring.factories 文件。
- Spring Boot 2.7+ 必须用
AutoConfiguration.imports,否则你的自定义自动配置不会被识别 -
spring.factories已被标记为 deprecated,继续用会收到 warning,且在 Spring Boot 3.x 中彻底移除 - 该文件里写的类必须是带有
@Configuration的 Java 类,不能是接口或普通 POJO
自动配置类怎么被选中:@ConditionalXXX 系列到底在判断什么
自动配置类不是全量加载,每个类顶部都有一堆 @ConditionalOnClass、@ConditionalOnMissingBean 这类注解。它们不是“装饰”,而是硬性准入条件——任一不满足,整个配置类直接跳过,连字节码都不会进容器。
常见误判场景:
-
@ConditionalOnClass判断的是类是否在 classpath 上(即能否ClassLoader.loadClass()),不是是否已实例化。哪怕你没引入redis-starter,但手动加了lettuce-corejar,@ConditionalOnClass(RedisTemplate.class)仍可能通过,但后续因缺RedisConnectionFactorybean 报错 -
@ConditionalOnMissingBean默认只检查当前容器(不含 parent context),如果你在 WebMvcConfigurer 中提前注册了同类型 bean,自动配置里的@Bean就会被跳过,且无任何日志提示 -
@ConditionalOnProperty默认对matchIfMissing = false,即属性不存在时整个配置不生效;想让它“默认开启”,得显式写matchIfMissing = true
自动配置加载顺序为什么重要:@AutoConfigureBefore/@AutoConfigureAfter 不总管用
多个自动配置类之间有依赖关系,比如 DataSourceAutoConfiguration 必须在 JpaAutoConfiguration 之前完成,否则后者找不到 DataSource。Spring Boot 提供了 @AutoConfigureBefore 和 @AutoConfigureAfter,但它们只影响同一轮 AutoConfigurationImportSelector 加载的顺序,不控制跨模块或手动 @Import 的类。
真正起作用的其实是 @Order 或实现 AutoConfigurationImportFilter,但日常开发中更可靠的做法是:
- 优先用
@DependsOn("xxx")显式声明 bean 级依赖(仅限于同一配置类内) - 避免在自动配置类中直接 new 对象,一律走
@Bean+ 依赖注入,让 Spring 自动解析顺序 - 调试时加
--debug启动参数,看控制台输出的 “Exclusions” 和 “Negative matches” 部分,比猜顺序更准
为什么我的自动配置没生效:几个最常漏掉的细节
写完 AutoConfiguration.imports、加上 @Configuration、配好 @Conditional,还是不生效?大概率卡在这几个地方:
- 类路径没对:你的自动配置类必须在
src/main/java下,且包名不能以org.springframework或spring-boot开头(会被 Spring Boot 的过滤器直接忽略) - jar 没打进 classpath:如果打包成独立 starter,确认
pom.xml中spring-boot-configuration-processor是optional=true,否则可能污染使用者的编译环境 - 条件冲突:比如同时存在
@ConditionalOnClass(Netty.class)和@ConditionalOnClass(Tomcat.class),而项目里两个容器依赖都存在,结果整个配置类被跳过(AND 逻辑) - Spring Boot 版本差异:Spring Boot 3.x 要求所有自动配置类必须使用
@Configuration(proxyBeanMethods = false),否则启动报错
自动配置不是魔法,它是基于约定的条件装配机制。最麻烦的从来不是写多少代码,而是搞清哪一行 @Conditional 在哪一刻失败了——建议从 --debug 日志入手,别急着改代码。










