在使用 Spring Boot 进行开发时,我们常常会引入诸如 spring-boot-starter-web
、spring-boot-starter-data-jpa
等依赖,从而快速开启相关功能模块。但你是否思考过这些 Starter 是如何构建的?如果我们要开发自己的 Starter,又该如何入手?
本文将从原理与实践两个角度,详细解析 Spring Boot Starter 的生成机制,并带你一步步创建一个自定义 Starter。
一、什么是 Spring Boot Starter?
Spring Boot 的 Starter 本质上是一组 预定义的依赖集合,旨在通过统一封装常用的配置、Bean 和依赖库,降低上手成本,提高项目的一致性与开发效率。
常见 Starter 示例:
Starter 名称 | 功能 |
---|---|
spring-boot-starter-web | 包含 Spring MVC、Jackson、嵌入式 Tomcat 等 |
spring-boot-starter-data-jpa | 包含 Spring Data JPA、Hibernate 等 |
spring-boot-starter-test | 包含 JUnit、Mockito 等测试库 |
本质:
Starter 本质上就是一个 Maven 或 Gradle 的普通依赖,通常由以下结构组成:
- 自动配置类(
@Configuration
+@Conditional*
) - Spring Factories 注册文件
- 相关依赖
二、Starter 的核心机制原理
1. 自动配置(Auto Configuration)
Spring Boot 的自动配置依赖于两个核心组件:
@EnableAutoConfiguration
spring.factories
中配置的自动配置类
Spring Boot 启动时会扫描依赖中的 META-INF/spring.factories
文件,并加载其中声明的 EnableAutoConfiguration
类。
# spring-boot-autoconfigure 包中
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autoconfig.MyServiceAutoConfiguration
2. 条件注解(@Conditional 系列)
Starter 中的自动配置通常不是强制生效的,而是基于条件。例如:
@Configuration
@ConditionalOnClass(MyService.class) // 仅当 classpath 中存在该类时才生效
@ConditionalOnMissingBean(MyService.class) // 若用户未定义此 bean 时自动配置
public class MyServiceAutoConfiguration {
@Bean
public MyService myService() {
return new MyService();
}
}
Spring Boot 提供了丰富的条件注解,如:
@ConditionalOnClass
@ConditionalOnMissingBean
@ConditionalOnProperty
@ConditionalOnResource
这使得 Starter 能够根据用户配置进行动态装配,具备高度灵活性。
三、自定义 Spring Boot Starter 实践
1. 创建两个模块
我们推荐将 Starter 分为两个模块:
(1)my-spring-boot-starter-autoconfigure
- 包含核心配置类、Bean、
spring.factories
- 不依赖 Spring Boot Starter 本身,便于独立测试和复用
(2)my-spring-boot-starter
- 仅引入
my-spring-boot-starter-autoconfigure
与所需依赖(如日志库、Spring Web 等) - 供外部项目使用
2. 编写自动配置类
@Configuration
@ConditionalOnClass(MyService.class)
@ConditionalOnMissingBean
public class MyServiceAutoConfiguration {
@Bean
public MyService myService() {
return new MyService("默认配置");
}
}
3. 注册自动配置类
在 my-spring-boot-starter-autoconfigure
的 resources/META-INF/spring.factories
文件中:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autoconfig.MyServiceAutoConfiguration
Spring Boot 2.7 及以后版本推荐使用
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
。
4. 打包发布
分别将 starter-autoconfigure
和 starter
打成 jar 包,并发布至私服或 Maven 中央库。
四、整合属性配置(可选)
为了增强 Starter 的可配置性,可以整合 @ConfigurationProperties
。
示例:
@ConfigurationProperties(prefix = "my.service")
public class MyServiceProperties {
private String name = "默认名称";
// getter & setter
}
@Configuration
@EnableConfigurationProperties(MyServiceProperties.class)
public class MyServiceAutoConfiguration {
@Bean
public MyService myService(MyServiceProperties properties) {
return new MyService(properties.getName());
}
}
用户项目中即可通过 application.yml
覆盖默认配置:
my:
service:
name: 自定义名称
五、与 Spring Boot 官方 Starter 的区别
官方 Starter | 自定义 Starter |
---|---|
功能强大、通用性广 | 适用于内部统一配置 |
发布在 Maven Central | 可发布至公司私服 |
通常有多个子模块 | 结构自由,便于维护 |
六、结语
Spring Boot Starter 是实现模块化、自动化配置的关键利器。通过本篇内容,我们系统性地理解了 Starter 的构建原理及其核心机制,并掌握了开发一个自定义 Starter 的完整流程。
掌握 Starter 的构建技巧,不仅能提升开发效率,也为你在团队中构建标准化基础组件打下坚实基础。
附:自定义 Starter 项目结构示意
my-spring-boot-starter/
├── my-spring-boot-starter/
│ └── pom.xml (依赖 my-spring-boot-starter-autoconfigure)
└── my-spring-boot-starter-autoconfigure/
├── src/main/java/
│ └── com/example/autoconfig/
│ ├── MyServiceAutoConfiguration.java
│ └── MyServiceProperties.java
├── src/main/resources/
│ └── META-INF/
│ └── spring.factories
└── pom.xml