文章
如何自定义一个Spring Boot Starter
从头创建一个自定义的 Spring Boot Starter
目录
自定义 Spring Boot Starter 步骤指南#
本文档演示如何从头创建一个自定义的 Spring Boot Starter,并针对每段核心代码做详细注释,帮助你理解其作用。#
1. 创建父级 Maven 项目#
首先创建一个父级 POM 以统一管理多个子模块的版本和依赖。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 \
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>custom-starter-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>custom-starter</module>
<module>custom-autoconfigure</module>
</modules>
<properties>
<java.version>11</java.version> <!-- 全局 Java 版本 -->
<spring.boot.version>2.7.0</spring.boot.version> <!-- Spring Boot 依赖版本 -->
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
说明
packaging设置为pom,表示这是一个聚合项目,不会生成可执行 JAR,只会聚合子模块。<modules>中列出子模块名称,Maven 会在构建时同步构建它们。<dependencyManagement>导入 Spring Boot 的 BOM,统一管理 Spring 相关依赖版本。
2. 编写 Starter 模块 (custom-starter)#
Starter 模块主要负责对外暴露依赖与注解,最终将自动配置模块打包进来。
为何分为两个模块 (Starter 与 AutoConfigure)? 1. 职责分离:Starter 模块仅包含对外暴露的 API 和注解;AutoConfigure 模块负责实际的自动配置逻辑。 2. 降低依赖耦合:当用户只需要注解或简单引用时,不会不必要地引入所有自动配置实现。 3. 增强可维护性:将不同关注点分离,便于模块独立升级、测试与发布。 4. 遵循 Spring Boot 社区最佳实践:大多数官方 Starter 均采用该双模块结构,保持一致性。
2.1 custom-starter/pom.xml#
<project xmlns="http://maven.apache.org/POM/4.0.0">
<parent>
<groupId>com.example</groupId>
<artifactId>custom-starter-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>custom-starter</artifactId>
<packaging>jar</packaging>
<dependencies>
<!-- 引入自动配置模块 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>custom-autoconfigure</artifactId>
</dependency>
</dependencies>
</project>
说明
- 继承父 POM,复用版本和依赖管理。
- 引入
custom-autoconfigure,实际提供功能的自动配置逻辑都在该模块中。
2.2 创建使用注解(可选)#
// src/main/java/com/example/starter/EnableCustomFeature.java
package com.example.starter;
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(CustomAutoConfiguration.class)
public @interface EnableCustomFeature {
}
说明
- 定义一个元注解
@EnableCustomFeature,用户只需在主应用类上添加此注解即可启用自动配置。 @Import(CustomAutoConfiguration.class)将自动配置类导入 Spring 上下文。
3. 编写自动配置模块 (custom-autoconfigure)#
自动配置模块是真正实现功能的地方,通过条件注解和 spring.factories 实现自动化加载。
3.1 custom-autoconfigure/pom.xml#
<project xmlns="http://maven.apache.org/POM/4.0.0">
<parent>
<groupId>com.example</groupId>
<artifactId>custom-starter-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>custom-autoconfigure</artifactId>
<packaging>jar</packaging>
<dependencies>
<!-- spring-boot-autoconfigure 提供基础设施 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<!-- 生成配置元数据,支持 IDE 自动补全 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>META-INF/**</include>
</includes>
</resource>
</resources>
</build>
</project>
说明
spring-boot-autoconfigure提供自动配置的基础包。spring-boot-configuration-processor用于在编译时生成配置属性提示。- 将
META-INF下的资源打包到最终 JAR。
3.2 自动配置类#
// src/main/java/com/example/autoconfigure/CustomAutoConfiguration.java
package com.example.autoconfigure;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConditionalOnProperty(prefix = "custom.feature", name = "enabled", havingValue = "true", matchIfMissing = true)
public class CustomAutoConfiguration {
@Bean
public CustomService customService() {
return new CustomService();
}
}
// src/main/java/com/example/autoconfigure/CustomService.java
package com.example.autoconfigure;
public class CustomService {
public void doSomething() {
System.out.println("CustomService is working");
}
}
说明
@Configuration标记该类为配置类。@ConditionalOnProperty只有在custom.feature.enabled=true(或属性缺失)时才生效,实现可开关控制。@Bean注解将CustomService注入到 Spring 容器,供外部使用。
3.3 spring.factories 配置#
# src/main/resources/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autoconfigure.CustomAutoConfiguration
说明
- 该文件告诉 Spring Boot 在启动时通过 SPI 加载
CustomAutoConfiguration,无需手动@Import。
4. 使用示例#
通过引入 Starter 依赖并添加注解或配置,即可开箱即用。
- 导入依赖
<dependency>
<groupId>com.example</groupId>
<artifactId>custom-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
说明: 将打好的 Starter JAR 加入项目。
- 启用注解(可选)
@SpringBootApplication
@EnableCustomFeature // 启用自定义功能
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
说明: 如果不想使用注解方式,也可单纯依赖 spring.factories 实现自动加载。
- 配置开关
custom.feature.enabled=true
说明: 通过配置文件控制功能开启或关闭。
- 调用示例
@RestController
public class TestController {
private final CustomService customService;
public TestController(CustomService customService) {
this.customService = customService;
}
@GetMapping("/test")
public String test() {
customService.doSomething();
return "OK";
}
}
说明: 注入并调用 CustomService,验证自动配置是否生效。
至此,一个完整且注释详尽的自定义 Spring Boot Starter 已创建完成。可根据实际需求扩展更多条件、属性以及回调。