Starter“开箱即用”需满足三前提:artifactId必须以-spring-boot-starter结尾;autoconfigure模块须与starter物理分离;且META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports路径准确、内容规范。

Starter 能做到“开箱即用”,前提是它被 Spring Boot 正确识别并加载自动配置类;否则哪怕代码写得再标准,@Configuration 也不会执行——根本原因往往就卡在命名或模块拆分上。
starter 的 artifactId 必须以 -spring-boot-starter 结尾
Spring Boot 启动时只扫描符合命名规范的依赖:只有 artifactId 以 -spring-boot-starter 结尾的 jar,才会被纳入自动配置候选范围。其他名字一律跳过,连 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 都不会读。
-
mycompany-redis-spring-boot-starter✅ 启动时自动加载配置 -
mycompany-redis-starter❌ 不会触发任何自动装配 -
mycompany_redis_spring_boot_starter❌ 下划线不被识别 -
mycompany-spring-boot-starter-web❌ 带-web后缀可能引发依赖冲突,且不符合命名语义
如果历史项目已用了非标准名,临时解法是手动加 @SpringBootApplication(scanBasePackages = "com.mycompany.autoconfig"),但这等于放弃 Starter 的设计契约,后续升级、条件注解都会不可靠。
autoconfigure 模块必须与 starter 模块物理分离
把自动配置逻辑和依赖声明混在一个模块里,会导致所有引入该 starter 的项目被迫继承你不想要的依赖——比如一个纯定时任务服务,因为 autoconfigure 模块里写了 spring-boot-starter-web,结果启动时报 ClassNotFoundException: DispatcherServlet。
-
mycompany-spring-boot-autoconfigure模块:只依赖spring-boot-autoconfigure、spring-context,按需引入底层 SDK(如lettuce-core),绝不含任何spring-boot-starter-xxx -
mycompany-spring-boot-starter模块:pom.xml 里只声明对mycompany-spring-boot-autoconfigure和spring-boot-starter(BOM)的依赖,不写任何 Java 代码
这种拆分不是为了“看起来规范”,而是保障依赖干净、场景可控。你无法预判下游项目是否需要 Web、Actuator 或 TestSupport,所以 autoconfigure 层必须保持最小侵入性。
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件必须存在且路径准确
Spring Boot 3.x(及 2.7+)已废弃 spring.factories,改用 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports。路径错一个字母、文件名少个点,配置类就彻底失效。
- 文件位置必须是:
src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports - 每行只能写一个自动配置类的全限定名,不能有空格、注释或空行:
com.mycompany.starter.redis.RedisAutoConfiguration - 如果用了
@ConditionalOnClass+@ConditionalOnMissingBean组合,注意顺序:前者失败则整个类跳过,后者根本不会执行
常见排查点:IDE 编译后没把该文件打进 jar;Maven 多模块构建时 resources 没正确 copy;或者路径写成 META-INF/spring/autoconfigure.imports(漏了完整包名)。
@ConfigurationProperties 绑定的 prefix 必须与 application.yml 中的实际前缀完全一致
配置项不生效,90% 是因为 @ConfigurationProperties(prefix = "my.redis") 和 yml 里的 my-redis: 或 myredis: 对不上。Spring Boot 不做模糊匹配,大小写、中划线、点号都严格区分。
- yml 中写
my.redis.host: localhost→ prefix 必须是"my.redis" - yml 中写
my-redis.host: localhost→ prefix 必须是"my-redis"(此时需配合@ConfigurationPropertiesBinding自定义转换器) - 别在 prefix 里写
${}占位符,它不会被解析
更隐蔽的问题是:如果属性类没加 @EnableConfigurationProperties(MyProperties.class) 或没在自动配置类上用 @EnableConfigurationProperties,即使 yml 写对了,字段也始终为 null——这个注解不是可选的,是绑定生效的前提。
真正难的不是写配置类,而是让整个链路不掉链子:从 Maven 坐标命名、模块职责划分、资源文件路径、条件注解顺序,到 yml 键名拼写,任意一环出错,表现都是“配置没生效”“Bean 没注入”“starter 像没引入一样”。这些地方没有报错,只有静默失效,最容易被当成“玄学问题”反复折腾。

















