跳到主要内容
实战:从零构建自定义 Spring Boot Starter | 极客日志
Java java
实战:从零构建自定义 Spring Boot Starter Spring Boot Starter 构建指南。详解从零搭建自定义 Starter 的全流程,包括基础概念、目录结构、自动配置类编写、元数据生成及本地仓库安装测试。通过实践掌握条件注解、SPI 机制及依赖管理,实现功能模块的解耦与复用。支持私有库发布及 Maven Central 部署流程,帮助开发者深入理解 Spring Boot 启动原理与自动配置机制。
基础知识
Spring Boot Starter 本质上是一个封装好的依赖模块,方便开发者快速引入所需功能。自定义 Starter 通常包括自动配置类、条件注解、属性配置类,以及 Maven/Gradle 的依赖管理。
核心组件:
配置属性类(@ConfigurationProperties) :绑定 application.properties 中的自定义配置。
自动配置类(@Configuration + 条件注解) :通过 @ConditionalOnClass、@ConditionalOnProperty 等实现条件化 Bean 注册。
依赖声明(pom.xml) :最小化依赖传递,通过 optional=true 控制非必要依赖。
目录结构
我们先看一下待会要创建的 SpringBootStarter 项目文件结构:
(此处展示项目目录结构)
实践构建
Spring Boot Starter 项目创建
首先使用 Maven 创建一个空的 Java 项目 spring-boot-starter-demo,在 pom.xml 中加入 SpringBoot 依赖以及 Starter 规范依赖。
1. Spring Boot Starter Maven 依赖
<dependencies >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-autoconfigure</artifactId >
</dependency >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-configuration-processor</artifactId >
<optional > true</optional >
</dependency >
org.projectlombok
lombok
true
<dependency >
<groupId >
</groupId >
<artifactId >
</artifactId >
<optional >
</optional >
</dependency >
</dependencies >
此外,为了在之后的 SpringBoot 测试项目引入,pom 文件中必须有这样的信息声明:
<groupId > com.cxytiandi</groupId >
<artifactId > spring-boot-starter-demo</artifactId >
<version > 1.0.0-SNAPSHOT</version >
<name > SpringBootStarterDemo</name >
<description > 自定义 SpringBootStarter 示例</description >
2. 配置属性类 创建一个配置类,用于在属性文件中配置值,绑定 application.properties 中自定义的配置。
package com.cxytiandi.demo;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties("spring.user")
public class UserProperties {
private String name;
}
3. 定义 Client 再定义一个 Client,里面定义一个方法,用于获取配置中的值。
package com.cxytiandi.demo;
public class UserClient {
private final UserProperties userProperties;
public UserClient (UserProperties userProperties) {
this .userProperties = userProperties;
}
public String getName () {
return userProperties.getName();
}
}
自动创建客户端 上面已经具备了最基本的 Starter 的包,不过现在还不能使用 UserClient,因为还没有它的实例。我们通过编写自动配置类,使用 @Configuration 和 @Conditional 注解实现条件化自动配置,创建实例。
@Bean
@ConditionalOnProperty(prefix = "spring.user", name = "enabled", havingValue = "true")
public UserClient userClient (UserProperties userProperties) {
return new UserClient (userProperties);
}
Spring Boot 通过 SPI(Service Provider Interface)识别自动配置类。Spring Boot 会默认扫描跟启动类平级的包,假如我们的 Starter 跟启动类不在同一个主包下,如何能让 UserAutoConfigure 生效?在 resources 下创建一个 META-INF 文件夹,然后在 META-INF 文件夹中创建一个 spring.factories 文件,文件中指定自动配置的类:
org.springframework.boot.autoconfigure.EnableAutoConfiguration =com.cxytiandi.demo.UserAutoConfigure
编写元数据 (可选) 生成配置提示信息,方便开发者在 IDE 中使用。
路径:src/main/resources/META-INF/spring-configuration-metadata.json
{
"groups" : [
{
"name" : "spring.user" ,
"type" : "com.cxytiandi.demo.UserProperties" ,
"sourceType" : "com.cxytiandi.demo.UserProperties"
}
] ,
"properties" : [
{
"name" : "spring.user.name" ,
"type" : "java.lang.String" ,
"description" : "用户名称配置,用于标识当前用户" ,
"defaultValue" : null
}
]
}
Starter 安装到本地仓库 当我们在 Starter 项目中执行 mvn install 命令时,Maven 会编译代码并打包成 JAR 文件,同时将 JAR 文件、POM 文件等元数据存入本地仓库,路径为:
~/.m2/repository /com/cxytiandi /spring-boot-starter-demo/ 1.0 .0 -SNAPSHOT /
其中包含 spring-boot-starter-demo-1.0.0-SNAPSHOT.jar 和 spring-boot-starter-demo-1.0.0-SNAPSHOT.pom。本地开发时,只要 Starter 已通过 mvn install 安装到本地仓库,测试项目就能直接引用。接下来我们进行一下测试自定义的 Starter。
测试 Starter 新建一个 SpringBoot 项目,在 pom.xml 添加本地 Starter 依赖。
1. SpringBootStarter 使用 Maven 配置 <dependencies >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-web</artifactId >
</dependency >
<dependency >
<groupId > org.projectlombok</groupId >
<artifactId > lombok</artifactId >
<optional > true</optional >
</dependency >
<dependency >
<groupId > com.cxytiandi</groupId >
<artifactId > spring-boot-starter-demo</artifactId >
<version > 1.0.0-SNAPSHOT</version >
</dependency >
</dependencies >
引入之后就直接可以使用 UserClient,UserClient 在项目启动的时候已经自动初始化好。
2. 客户端使用 @RestController
public class UserController {
@Autowired
private UserClient userClient;
@GetMapping("/user/name")
public String getUserName () {
return userClient.getName();
}
}
3. 配置属性文件中启动 spring.user.name=yinjihuan
spring.user.enabled=true
4. 结果 访问 /user/name 就可以返回我们配置的 yinjihuan。
使用注解开启 Starter 自动构建 在之前我们使用的是通过在 resources 下创建一个 META-INF 文件夹的 spring.factories 文件,其实也可以通过注解的方式来开启是否自动配置。如果用注解的方式,那么 spring.factories 就不需要编写了。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({UserAutoConfigure.class})
public @interface EnableUserClient {}
这段代码的核心是 @Import({UserAutoConfigure.class}),通过导入的方式实现把 UserAutoConfigure 实例加入 SpringIOC 容器中,这样就能开启自动配置了。使用方式就是我们在测试项目 SpringBootDemoApplication 中的启动类上加上该注解,就能使用自定义 Starter 了。
@SpringBootApplication
@EnableUserClient
public class SpringBootDemoApplication {
public static void main (String[] args) {
SpringApplication.run(SpringBootDemoApplication.class, args);
}
}
打包与发布 当然自定义 Starter 完后,我们可以构建 Jar 包并发布到 Maven 仓库,Maven 仓库分为公共库以及私有库。
1. 构建 Jar 包
mvn clean package
mvn clean install
2. 发布到 Maven 仓库 如果是公共库,注册到 Maven Central。Maven Central 是全球最大的公共 Maven 仓库,需通过 Sonatype Nexus Repository Manager 提交。
访问 Sonatype Jira 注册页面,创建账号并提交项目申请(需提供 groupId 对应的域名所有权证明,如 com.cxytiandi 需拥有 cxytiandi.com 域名)。
生成 GPG 签名
<project >
<properties >
<gpg.executable > gpg</gpg.executable >
<gpg.passphrase > 你的 GPG 密钥密码</gpg.passphrase >
</properties >
<distributionManagement >
<snapshotRepository >
<id > sonatype-nexus-snapshots</id >
<url > https://s01.oss.sonatype.org/content/repositories/snapshots/</url >
</snapshotRepository >
<repository >
<id > sonatype-nexus-staging</id >
<url > https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url >
</repository >
</distributionManagement >
<licenses >
<license >
<name > The Apache License, Version 2.0</name >
<url > http://www.apache.org/licenses/LICENSE-2.0.txt</url >
</license >
</licenses >
<developers >
<developer >
<name > Your Name</name >
<email > [email protected] </email >
</developer >
</developers >
</project >
mvn clean deploy -P release-sonatype
mvn clean deploy -P release-sonatype -DskipTests
在 Maven Central 验证
提交后等待 Sonatype 审核(通常 1-2 小时),审核通过后,运行以下命令同步索引:
mvn versions:update-release-repository
<distributionManagement >
<snapshotRepository >
<id > nexus-snapshots</id >
<url > http://your-nexus-server/repository/maven-snapshots/</url >
</snapshotRepository >
<repository >
<id > nexus-releases</id >
<url > http://your-nexus-server/repository/maven-releases/</url >
</repository >
</distributionManagement >
<servers >
<server >
<id > nexus-snapshots</id >
<username > 仓库用户名</username >
<password > 仓库密码</password >
</server >
<server >
<id > nexus-releases</id >
<username > 仓库用户名</username >
<password > 仓库密码</password >
</server >
</servers >
mvn clean deploy -DaltSnapshotRepository=nexus-snapshots::default::http://your-nexus-server/repository/maven-snapshots/
mvn clean deploy -DaltRepository=nexus-releases::default::http://your-nexus-server/repository/maven-releases/
总结 本期博客从零开始搭建 Spring Boot Starter,学习完后,我们可以更深入理解 Spring Boot Starter 的内部原理,能够更好的理解 SpringBoot 的启动流程以及增加对 SpringBoot 自动配置的理解。
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online