SpringBoot自定义Starter

前言 :SpringBoot最核心的优势之一就是Starter 场景启动器 ,依托自动装配机制实现"开箱即用、零冗余配置"。官方提供了Web、JDBC、Redis等通用Starter,但业务中通用场景无法覆盖所有定制需求,比如自定义接口限流、日志脱敏、统一返回封装、自定义监控等,此时就需要自定义Starter实现业务能力封装、项目复用、解耦通用逻辑。

一、Starter核心认知:为什么需要自定义Starter?

1.1 Starter核心作用

Starter(场景启动器)是SpringBoot为场景化自动装配设计的依赖封装组件,核心作用:整合场景所需依赖、自动加载配置类、初始化核心Bean,开发者只需引入依赖,无需手动配置即可使用对应功能。

简单来说:Starter = 依赖聚合 + 自动配置 + 场景能力封装,彻底告别传统SSM的繁琐配置。

1.2 自定义Starter的适用场景

  • 项目通用工具能力封装:统一日志、统一异常处理、接口加密解密

  • 通用业务组件复用:分页封装、字典转换、权限校验、限流熔断

  • 第三方工具适配:自定义SDK整合、中间件二次封装

  • 团队统一规范:统一配置、统一返回体、全局拦截器

1.3 官方Starter与自定义Starter区别

  • 官方Starter :前缀固定 spring-boot-starter-xxx,适配通用技术场景,由Spring官方维护

  • 自定义Starter :后缀固定 xxx-spring-boot-starter,适配业务定制场景,由团队自行维护

核心规范(生产必遵守) :自定义Starter绝对不能使用 spring-boot-starter-xxx 前缀,避免与官方组件冲突。

二、Starter底层核心结构(重中之重)

很多人误以为Starter包含业务代码,这是核心误区!参考Spring官方源码设计,标准自定义Starter必须分为两个模块,缺一不可:

2.1 两大核心模块分工

2.1.1 starter启动器模块(空壳模块)

纯依赖管理模块,无任何业务代码、无配置代码,仅负责聚合依赖,统一管理版本,简化项目引入成本。

作用:业务项目只需引入该Starter依赖,无需手动引入autoconfigure模块及相关第三方依赖,实现一键引入。

2.1.2 autoconfigure自动配置模块(核心功能模块)

真正承载所有功能的核心模块,包含:配置属性类、自动配置类、业务组件、条件注解、SPI配置文件。

作用:完成Bean自动装配、配置绑定、条件生效、组件初始化,是Starter功能实现的核心。

2.2 完整依赖链路

业务项目 → 引入 starter模块 → starter模块依赖 autoconfigure模块 → autoconfigure模块完成自动装配

该结构是Spring官方标准设计,优势:解耦依赖管理与功能实现、便于版本维护、功能可复用、无侵入拓展

三、自动装配核心注解体系(源码底层依赖)

自定义Starter的核心就是手动实现自动配置类,所有自动装配能力都依赖SpringBoot条件注解,参照官方Web自动配置类规范,核心注解汇总:

  • @Configuration:标记当前类为自动配置类,Spring启动时扫描加载

  • @ConditionalOnXXX:条件生效注解,满足条件才加载当前配置类/Bean(核心)

  • @EnableConfigurationProperties:开启配置属性绑定,将配置文件参数绑定到实体类

  • @ConfigurationProperties:配置属性绑定注解,定义配置前缀,映射yml/properties配置

  • @AutoConfigureOrder:指定自动配置类加载优先级

  • @AutoConfigureAfter:指定当前配置类在某个官方配置类之后加载,保证依赖顺序

  • @Bean:注册自定义组件到Spring IoC容器

  • @ConditionalOnMissingBean:容器无对应Bean时才创建,支持用户自定义覆盖默认组件

四、从零手写自定义Starter(完整实操)

我们将搭建一个自定义欢迎页Starter,实现:引入依赖后,根据配置文件参数自动生成首页访问接口,无配置则不生效,完全贴合生产场景。

4.1 整体工程结构

父工程:springboot_custome_starter(统一版本管理)

子模块1:tulingxueyuan-spring-boot-starter(空壳启动器)

子模块2:tulingxueyuan-spring-boot-autoconfigure(自动配置核心)

4.2 步骤1:创建父工程统一管理版本

父工程为pom打包方式,统一继承SpringBoot父依赖,管理所有子模块版本,避免版本冲突。

复制代码
<?xml version="1.0" encoding="UTF‐8"?>
<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 https://maven.apache.org/xsd/maven‐4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- 子模块管理 -->
    <modules>
        <module>tulingxueyuan‐spring‐boot‐starter</module>
        <module>tulingxueyuan‐spring‐boot‐autoconfigure</module>
    </modules>

    <!-- 继承SpringBoot父工程 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring‐boot‐starter‐parent</artifactId>
        <version>2.3.6.RELEASE</version>
        <relativePath/>
    </parent>

    <groupId>com.tulingxueyuan.springboot</groupId>
    <artifactId>springboot_custome_starter</artifactId>
    <version>0.0.1‐SNAPSHOT</version>
    <name>springboot_custome_starter</name>
    <description>SpringBoot自定义Starter父工程</description>

    <packaging>pom</packaging>
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring‐boot‐starter</artifactId>
        </dependency>
    </dependencies>
</project>

4.3 步骤2:创建空壳Starter启动器模块

该模块无任何代码,仅依赖autoconfigure核心模块,实现依赖统一聚合。

复制代码
<?xml version="1.0" encoding="UTF‐8"?>
<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">
    <parent>
        <artifactId>springboot_custome_starter</artifactId>
        <groupId>com.tulingxueyuan.springboot</groupId>
        <version>0.0.1‐SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <artifactId>tulingxueyuan‐spring‐boot‐starter</artifactId>
    <description>自定义Starter空壳启动器,仅做依赖管理</description>

    <dependencies>
        <!-- 引入自动配置核心模块 -->
        <dependency>
            <groupId>com.tulingxueyuan.springboot</groupId>
            <artifactId>tulingxueyuan‐spring‐boot‐autoconfigure</artifactId>
            <version>0.0.1‐SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

注意:使用IDE初始化的模块,需删除启动类、resources默认文件、test测试目录,保证纯空壳模块。

4.4 步骤3:创建autoconfigure自动配置核心模块

该模块承载所有功能代码、配置绑定、自动装配逻辑,引入web依赖和配置处理器依赖。

复制代码
<?xml version="1.0" encoding="UTF‐8"?>
<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">
    <parent>
        <artifactId>springboot_custome_starter</artifactId>
        <groupId>com.tulingxueyuan.springboot</groupId>
        <version>0.0.1‐SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <artifactId>tulingxueyuan‐spring‐boot‐autoconfigure</artifactId>

    <dependencies>
        <!-- Web核心依赖,用于开发接口组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring‐boot‐starter‐web</artifactId>
        </dependency>
        <!-- 配置文件处理器,配置绑定自动提示、校验 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring‐boot‐configuration‐processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>

4.5 步骤4:编写配置属性绑定类

用于绑定 application.properties/yml 中的自定义配置,实现配置化控制功能开关与参数。

复制代码
package com.starter.tulingxueyuan;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * 自定义Starter配置属性绑定类
 * 配置前缀:tuling.hello
 */
@ConfigurationProperties("tuling.hello")
public class HelloProperties {

    // 自定义欢迎名称
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

4.6 步骤5:编写核心业务组件(接口Controller)

自定义业务组件,读取配置参数,实现接口能力。

复制代码
package com.starter.tulingxueyuan;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * 自定义Starter核心接口组件
 */
@RestController
public class IndexController {

    @Resource
    private HelloProperties helloProperties;

    @RequestMapping("/")
    public String index(){
        // 读取配置文件参数,动态返回欢迎信息
        return helloProperties.getName() + "欢迎您";
    }
}

4.7 步骤6:编写自动配置类(核心核心)

通过条件注解控制组件生效时机,开启配置绑定,自动注册Bean到容器。实现:配置文件存在tuling.hello.name参数时,才生效创建接口

复制代码
package com.starter.tulingxueyuan;

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 自定义Starter自动配置类
 */
@Configuration
// 开启配置属性绑定,将HelloProperties纳入容器管理
@EnableConfigurationProperties(HelloProperties.class)
// 条件注解:存在指定配置参数时,当前自动配置类才生效
@ConditionalOnProperty(value = "tuling.hello.name")
public class HelloAutoConfig {

    @Bean
    public IndexController indexController(){
        return new IndexController();
    }
}

4.8 步骤7:配置SPI加载文件(SpringBoot2.x核心)

SpringBoot2.x 依靠 META-INF/spring.factories 实现自动配置类的SPI加载,Spring启动时自动扫描该文件,加载自定义自动配置类。

在autoconfigure模块的 resources 目录下,创建 META-INF/spring.factories 文件,内容如下:

复制代码
# 自动配置类注册
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.starter.tulingxueyuan.HelloAutoConfig

SpringBoot3.x版本拓展 :3.x废弃spring.factories,需在META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中写入自动配置类全类名。

4.9 步骤8:打包安装Starter

通过Maven依次执行 clean → install,将两个模块打包到本地Maven仓库,供其他项目引入使用。打包顺序:先autoconfigure模块,后starter空壳模块

五、测试自定义Starter(完整验证流程)

5.1 新建测试项目,引入自定义Starter依赖

复制代码
<dependency>
    <groupId>com.tulingxueyuan.springboot</groupId>
    <artifactId>tulingxueyuan‐spring‐boot‐starter</artifactId>
    <version>0.0.1‐SNAPSHOT</version>
</dependency>

5.2 无配置测试(验证条件生效)

不配置任何参数,启动项目,访问localhost:8080,返回404。

原因 :自动配置类添加了 @ConditionalOnProperty 条件注解,无对应配置则不加载Bean,接口不生效,符合预期。

5.3 添加配置测试(验证功能生效)

在application.properties中添加自定义配置:

复制代码
tuling.hello.name=学院

重启项目,访问 localhost:8080,成功返回:学院欢迎您,Starter功能生效。

六、核心源码链路解读

6.1 自定义Starter加载完整时序

  1. 业务项目引入自定义Starter依赖,间接引入autoconfigure模块;

  2. SpringBoot启动时,通过SPI机制扫描 spring.factories 文件;

  3. 读取自定义自动配置类HelloAutoConfig,纳入自动配置候选列表;

  4. 校验 @ConditionalOnProperty 条件,匹配配置文件参数;

  5. 条件成立,加载自动配置类,绑定配置属性到 HelloProperties

  6. 通过@Bean注解将IndexController注册到IoC容器;

  7. 容器刷新完成,接口生效,对外提供访问能力。

6.2 与SpringBoot启动原理联动

自定义Starter的加载时机,处于SpringBoot容器刷新阶段(refresh) ,由 AutoConfigurationImportSelector 扫描所有SPI配置的自动配置类,统一加载装配,和官方Web、JDBC自动配置加载逻辑完全一致。

七、生产优化与踩坑总结

7.1 生产优化方案

  • 支持用户自定义覆盖 :业务项目自定义同类型Bean时,优先使用用户Bean,在自动配置类添加 @ConditionalOnMissingBean

  • 完善条件注解 :搭配 @ConditionalOnClass@ConditionalOnWebApplication 精准控制生效场景

  • 默认值兜底:配置属性类设置默认值,避免空配置报错

  • 版本兼容:区分SpringBoot2.x与3.x SPI配置方式,适配新旧版本

7.2 常见踩坑点

  • SPI文件路径错误:必须放在 resources/META-INF 目录,文件名、后缀不能出错

  • 条件注解滥用:无条件注解会导致Bean强制加载,无法灵活开关功能

  • 模块结构错误:将业务代码写在starter空壳模块,不符合官方规范,无法复用扩展

  • 配置前缀不统一:绑定前缀与配置文件不一致,导致参数无法注入

八、面试高频总结(必背)

  1. 自定义Starter结构:分为starter空壳依赖模块、autoconfigure自动配置模块,前者管依赖聚合,后者管功能实现;

  2. 命名规范:官方前缀spring-boot-starter-xxx,自定义后缀xxx-spring-boot-starter;

  3. 核心原理:基于SPI机制+自动配置注解,实现Bean的条件化自动装配;

  4. 2.x与3.x差异:2.x基于spring.factories,3.x基于imports文件;

  5. 核心价值:业务能力封装、统一规范、开箱即用、无侵入复用、解耦核心业务与通用逻辑。

九、全文终极总结

自定义Starter是SpringBoot自动装配思想的最佳落地实践,核心就是通过SPI注册自动配置类,结合条件注解实现按需加载组件。标准的双模块结构保证了代码解耦、版本可控、复用性极强,是中高级开发、架构师必备能力,同时也是面试高频考点。

日常开发中,可将项目中所有通用、重复的功能封装为自定义Starter,统一团队开发规范,大幅提升项目开发效率与可维护性。

相关推荐
触底反弹1 小时前
⚡ Promise.all 性能优化:让 Agent 的工具调用飞起来
javascript·人工智能·后端
霸道流氓气质1 小时前
Windows 本地搭建 CDC 全链路测试环境(Kafka+Canel+binlog+SpringBoot)
windows·spring boot·kafka
程序员爱钓鱼1 小时前
Rust 控制流 if 详解:条件判断与 if 表达式
前端·后端·rust
Demon_Hao1 小时前
Spring Boot 4、JDK 25 与 GraalVM:Java 云原生进化,能否撼动 Go 的地位?
java·spring boot·云原生
kyle~2 小时前
Swagger ---基于 描述文件 生成 交互式API文档 的工具
前端·后端·规格说明书·说明文档
wuqingshun31415910 小时前
什么是责任链模式,一般用在什么场景?
java·责任链模式
江畔柳前堤10 小时前
GO01-Go 语言与主流编程语言深度对比
开发语言·人工智能·后端·微服务·云原生·golang·go
世界哪有真情11 小时前
拿人类意识卡 AI?等于用 bug 验收正式产品
前端·人工智能·后端
:-)11 小时前
算法-归并排序
java·开发语言·数据结构·算法·排序算法