当前位置: 首页 > news >正文

深入理解Spring Boot Starter及如何自定义Starter

深入理解Spring Boot Starter及如何自定义Starter

Spring Boot Starter本质上是一种依赖管理和自动配置机制。通过引入一个Starter依赖,可以自动引入并配置一系列相关组件,极大地简化开发流程。比如使用spring-boot-starter-web,可以自动引入Spring MVC、Tomcat服务器、JSON解析器等,无需手动逐个配置。

Starter的自动配置原理

Spring Boot 会扫描所有 classpath 下 JAR 包中的 META-INF/spring.factories 文件,并按照其中的配置进行自动加载。

📌 详细解析

  1. 扫描机制

    • Spring Boot 使用 SpringFactoriesLoader 类来加载 spring.factories 文件中的配置。
    • 它会扫描 所有 依赖(包括 libs/dependencies 目录中的 JAR 包),寻找 META-INF/spring.factories,然后合并所有的配置项。
  2. 合并机制

    • 如果多个 JAR 包(如 spring-boot-starter-webspring-boot-starter-data-jpa 等)都定义了 spring.factories,Spring Boot 会把 所有 JAR 包中的配置合并,然后执行加载。
    • 示例:
      • spring-boot-autoconfigure.jarMETA-INF/spring.factories 可能包含:
        org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
        org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
        org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
        
      • 另一个 JAR 包 my-custom-starter.jar 可能包含:
        org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
        com.example.custom.MyCustomAutoConfiguration
        
      • Spring Boot 会把这两部分合并,最终加载:
        org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
        org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
        org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
        com.example.custom.MyCustomAutoConfiguration
        
  3. 加载顺序

    • Spring Boot 不保证 spring.factories 配置的执行顺序,如果多个 JAR 包中存在相同的 Key(比如 EnableAutoConfiguration),它们都会被加载,但执行顺序不可预测
    • 如果需要控制加载顺序,可以使用 @AutoConfigureBefore@AutoConfigureAfter

META-INF/spring.factories 文件的作用

META-INF/spring.factoriesSpring Boot 的自动配置机制 之一,它的主要作用是:

  • 启用 Spring Boot 的自动配置(AutoConfiguration)
  • 自动注册 Spring 组件(如监听器、工厂类等)
  • 扩展 Spring Boot 功能

📌 spring.factories 作用范围

类型作用
EnableAutoConfiguration自动配置 Spring Boot 组件(最常见)
ApplicationContextInitializerSpring 上下文初始化时执行
ApplicationListener监听 Spring 事件
FailureAnalyzer处理异常分析,提供更友好的错误信息
EnvironmentPostProcessor修改 Spring Environment,在启动时修改配置

📌 SpringFactoriesLoader 如何扫描?

Spring Boot 使用 SpringFactoriesLoader.loadFactoryNames(Class<?> factoryType, ClassLoader classLoader) 方法来扫描所有 META-INF/spring.factories

public static List<String> loadFactoryNames(Class<?> factoryType, ClassLoader classLoader) {
    String factoryTypeName = factoryType.getName();
    return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}
  • loadSpringFactories(classLoader) 方法会 遍历所有 JAR 包,加载 spring.factories
  • 所有 JAR 包的 spring.factories 文件的内容都会被合并并解析

📌 如何避免 spring.factories 冲突?

如果多个 JAR 包的 spring.factories 中包含 相同的 Key,但不同的实现(比如多个 JAR 里都有 EnableAutoConfiguration),可能会导致:

  • 重复加载(多个类都被注册)
  • 冲突(不同的类覆盖了同一个 Bean)
解决方案
  1. 使用 spring-boot-autoconfigure 提供的新方式

    • Spring Boot 2.7+ 推荐使用 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
    • 这样可以更好地控制哪些配置应该被加载,不会导致 spring.factories 的全局合并问题。
  2. 使用 @ConditionalOnMissingBean 避免重复加载

    • 在自动配置类中使用 @ConditionalOnMissingBean,避免同一个 Bean 被多次注册:
    @Configuration
    @ConditionalOnClass(MyService.class)
    public class MyAutoConfiguration {
        @Bean
        @ConditionalOnMissingBean
        public MyService myService() {
            return new MyService();
        }
    }
    
  3. 使用 @AutoConfigureBefore@AutoConfigureAfter

    • 控制自动配置类的加载顺序:
    @Configuration
    @AutoConfigureBefore(DataSourceAutoConfiguration.class)
    public class MyCustomAutoConfiguration {
        // 自定义配置
    }
    

📌 结论

Spring Boot 确实会扫描所有 JAR 包的 META-INF/spring.factories 文件,并合并所有配置项
这使得 Starter 组件可以自动注册需要的 Bean 和配置,但也可能导致 Bean 冲突或重复加载的问题
Spring Boot 2.7+ 推荐使用 AutoConfiguration.imports 作为更可控的替代方案


如何自定义一个Starter(以钉钉异常通知为例)

假设你想要实现当接口异常发生时自动发送钉钉通知的功能,创建一个Starter将是一个理想选择。

1. 创建新项目模块

例如:mycompany-starter-dingtalk

四、Starter实现步骤

  • 创建自动配置类:
@Configuration
@ConditionalOnClass(DingTalkNotifier.class)
@EnableConfigurationProperties(DingTalkProperties.class)
public class DingTalkAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public DingTalkNotifier dingTalkNotifier(DingTalkProperties properties) {
        return new DingTalkNotifier(properties.getWebhookUrl());
    }

    @Bean
    public GlobalExceptionHandler globalExceptionHandler(DingTalkNotifier dingTalkNotifier) {
        return new GlobalExceptionHandler(dingTalkNotifier);
    }
}
  • 定义属性类绑定用户配置
@ConfigurationProperties(prefix = "dingding")
public class DingTalkProperties {
    private String webhookUrl;

    public String getWebhookUrl() { return webhookUrl; }
    public void setWebhookUrl(String webhookUrl) { this.webhookUrl = webhookUrl; }
}

在用户的application.yml中配置:

dingding:
  webhook-url: "https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN"

注册自动配置

在项目的resources目录下创建META-INF/spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.dingtalk.autoconfigure.DingTalkAutoConfiguration

Spring Boot启动时会自动扫描并加载这个配置。

五、Starter的命名规范建议

官方并没有强制性的命名约束,但 Spring Boot 社区和官方 Starter 一般遵循一些最佳实践,推荐使用 统一的命名规范,以提高可读性和易用性。

1️⃣ 官方 Starter 的命名规范

Spring Boot 官方 Starter 的命名规则通常是:

spring-boot-starter-<技术名称>
📌 典型官方 Starter 例子
Starter说明
spring-boot-starter-webWeb 开发 Starter,包含 Spring MVC、Tomcat 等
spring-boot-starter-data-jpaJPA 数据访问 Starter
spring-boot-starter-securitySpring Security Starter
spring-boot-starter-thymeleafThymeleaf 模板引擎 Starter

👉 结论:

  • 所有官方 Starter 以 spring-boot-starter- 开头,然后跟 具体的技术名称
  • 这让开发者一眼就能知道 它是官方的,并且它支持什么技术

2️⃣ 自定义 Starter 的推荐命名规则

对于 自定义 Starter,社区推荐使用:

<公司/团队前缀>-starter-<功能名称>

或者:

<组织名称>-spring-boot-starter-<功能名称>
📌 推荐命名方式
命名示例适用场景
mycompany-starter-dingtalk企业内部使用,用于钉钉异常通知
com-example-spring-boot-starter-logging社区 Starter,支持 Spring Boot 日志增强
custom-starter-redis通用 Starter,适用于 Redis 相关增强功能
awesome-spring-boot-starter-cache开源项目,提供缓存增强
📌 推荐命名规则

避免以 spring-boot-starter- 开头

  • 这样可以 避免和官方 Starter 混淆,让用户明确知道它是第三方 Starter
  • 推荐:mycompany-starter-xxxxxx-spring-boot-starter
  • 不推荐:spring-boot-starter-xxx ❌(可能导致误以为是官方的)

前缀代表团队或组织名称

  • 例如:
    • alibaba-starter-seata(阿里巴巴 Seata 事务管理)
    • baidu-starter-paddlepaddle(百度 PaddlePaddle AI 框架)
    • mycompany-starter-wechat(企业内部的微信消息推送)

后缀描述功能

  • starter-dingtalk(钉钉通知)
  • starter-mq(消息队列支持)
  • starter-log-enhancer(日志增强)

3️⃣ 约束和注意事项

🚀 官方约束

Spring Boot 不会 强制要求 Starter 必须符合某种命名规则,但官方有一些约定

  1. 官方 Starter 需要由 Spring 团队维护(放在 org.springframework.boot 下面)。
  2. 社区或第三方 Starter 不能以 spring-boot-starter- 开头,避免误导用户。
🚀 依赖命名

如果 Starter 需要提供 自动配置,通常需要提供:

  • 核心依赖(starter 依赖)
    <artifactId>mycompany-starter-dingtalk</artifactId>
    
  • 自动配置依赖(autoconfigure 依赖)
    <artifactId>mycompany-starter-dingtalk-autoconfigure</artifactId>
    

这样可以 拆分 Starter 的自动配置和核心功能,提高灵活性。

📌 结论

官方 Starterspring-boot-starter- 开头,后面跟具体技术,如 spring-boot-starter-web
自定义 Starter 推荐 mycompany-starter-xxxxxx-spring-boot-starter,避免与官方混淆。
组织前缀 可加 mycompany-com-example-,以区分不同的公司或团队。
最好拆分 starterstarter-autoconfigure,增强模块化和可扩展性

参考链接

  • Spring Boot 官方文档
  • Spring Boot Starters 官方介绍
  • Spring Boot AutoConfiguration 机制
    在这里插入图片描述

相关文章:

  • C++类对象创建全解析:从构造函数到内存管理
  • C++Primer学习(6.7 函数指针——难!)
  • Centos固定IP配置
  • 搜广推校招面经四十七
  • NaViT:训练任意分辨率和长宽比的 ViT
  • springboot新手入门搭建项目
  • 2025-3-13 leetcode刷题情况(贪心算法--区间问题)
  • Unity AI 技术浅析(三):智能代理(Agents)
  • 破解“光伏+储能+充电”一体化难题!安科瑞全方案打造智慧能源新标杆
  • RocketMQ面试题:进阶部分
  • Java开发第一坑:记一次MySQL ON DUPLICATE KEY UPDATE影响行数异常排查:从现象到解决的全过程
  • 【资料分享】标准规范汇总(2025.3.13更新)
  • 工程化与框架系列(32)--前端测试实践指南
  • 使用PHP进行自动化测试:工具与策略的全面分析
  • RagFlow+Deepseek构建个人知识库
  • 深入理解TCP/IP网络模型及Linux网络管理
  • modbusrtu.h:5:10: error: ‘QSerialPort‘ file not found
  • 技术视界|构建理想仿真平台,加速机器人智能化落地
  • 文件解析漏洞靶场通关合集
  • Java泛型(Generics(
  • 哪里的网站可以做围棋死活题/手机app免费制作平台
  • danbold做动漫的网站/百度竞价推广一个月多少钱
  • dede网站名称不能中文/长沙市seo百度关键词
  • 天津百度网站排名优化/广州seo招聘
  • 怎么做刷qq会员的网站/seo关键词排名优化联系方式
  • 用asp做的网站打开页面很慢/免费创建属于自己的网站