starter 的 artifactId 必须以 -spring-boot-starter 结尾,否则 Spring Boot 不会扫描其自动配置类;正确命名如 mycompany-spring-boot-starter,且需分离 autoconfigure 与 starter 模块,避免依赖污染。

starter 的命名必须以 -spring-boot-starter 结尾,否则 autoconfigure 不生效
Spring Boot 的自动装配机制靠 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(2.7+)或 META-INF/spring.factories(旧版)触发,但前提是 starter 的 artifactId 必须符合命名规范。如果起名 mycompany-common,哪怕包里写了 @EnableAutoConfiguration,Boot 启动时根本不会扫描它。
正确命名示例:mycompany-spring-boot-starter、mycompany-redis-spring-boot-starter。Maven 依赖引入后,Boot 才会把它纳入 auto-configuration 候选范围。
- 别用下划线代替中划线:
mycompany_starter❌,mycompany-spring-boot-starter✅ - 不要省略
-spring-boot-starter后缀,mycompany-starter也不行 - 若已有老项目用了非标准名,只能靠在主应用的
@SpringBootApplication上手动加scanBasePackages,但违背 starter 设计初衷
autoconfigure 模块不能直接依赖 spring-boot-starter
自定义 starter 通常拆成两部分:一个只含自动配置逻辑的 -autoconfigure 模块(无 web、无 actuator),另一个是对外暴露的 -spring-boot-starter 模块(只声明依赖)。如果把 spring-boot-starter-web 直接写进 autoconfigure 的 pom.xml,会导致所有引入该 starter 的项目被迫带上 web 依赖——哪怕它是个纯定时任务服务。
正确的依赖结构:
-
mycompany-spring-boot-starter:仅依赖mycompany-spring-boot-autoconfigure+spring-boot-starter(空的 BOM) -
mycompany-spring-boot-autoconfigure:只依赖spring-boot-autoconfigure、spring-context等底层 API,按需引入具体组件如lettuce-core,但绝不拉spring-boot-starter-xxx
否则你会看到启动时报错:ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet,而你的模块根本不需要 MVC。
@ConditionalOnClass 和 @ConditionalOnMissingBean 的组合顺序很关键
自动配置类里常要控制“有某个类才生效”“没某个 Bean 才注入”。但这两个条件不是并列判断,而是短路执行:Spring 先检查 @ConditionalOnClass,失败就跳过整个配置类;只有通过了,才继续判断 @ConditionalOnMissingBean。
比如封装一个默认 MyService 实现:
@Configuration
@ConditionalOnClass(MyService.class)
@ConditionalOnMissingBean(MyService.class)
public class MyAutoConfiguration {
@Bean
public MyService myService() {
return new DefaultMyService();
}
}
如果用户自己写了 @Bean MyService,这个配置类仍会加载(因为 MyService.class 存在),但 @Bean 方法不执行(因 missing 条件不满足)。可一旦把两个注解顺序颠倒,Spring 会先查有没有 MyService Bean,此时上下文为空,条件成立,接着再检查 @ConditionalOnClass ——但如果用户没引入相关 jar,MyService.class 根本不存在,整个配置类直接被忽略,连 fallback 都没机会。
- 优先用
@ConditionalOnClass做“能力探测”,再用@ConditionalOnMissingBean做“兜底注入” - 避免在同一个
@Bean上叠加多个@ConditionalOnXxx,语义易混淆;拆到类级别更清晰 - 测试时记得删掉用户自定义 Bean,验证 autoconfigure 是否真能 fallback
配置属性绑定必须用 @ConfigurationProperties,且 prefix 要唯一
用户通过 application.yml 配置你的组件行为,比如 mycompany.cache.ttl=60。这背后靠的是 @ConfigurationProperties(prefix = "mycompany.cache")。如果 prefix 写成 cache 或 redis,极易跟其他 starter 冲突——别人也用 redis.host,你的类一加载就报 BindingValidationException。
- prefix 必须带公司/产品前缀,如
mycompany.redis、mycompany.metrics - 类上必须加
@ConfigurationProperties,且需在 autoconfigure 模块中显式声明为@Bean或用@EnableConfigurationProperties - 不要用
@Value("${...}")注入配置项,它不支持松散绑定(mycompany.cache-ttl≠mycompany.cache_ttl),也不校验 - 加上
@Validated和字段级@NotBlank等注解,能让配置错误在启动时报明确提示,而不是运行时 NPE
真正麻烦的是跨模块引用:如果 starter A 和 B 都用了 mycompany.common prefix,又都声明了同名属性,Spring 会合并还是覆盖?答案是不确定——取决于加载顺序,这种耦合必须靠命名隔离来根除。

















