【Java后端】《Spring Boot Starter 原理详解》博客

Spring Boot Starter 原理详解

一、引言

Spring Boot 能够火遍全世界,很大程度上归功于它的 自动配置Starter 机制

在日常开发中,只需引入一个 spring-boot-starter-web,我们就能快速搭建 Web 服务,几乎不需要额外配置。这背后究竟是怎么实现的?Starter 又是什么?本文将深入解析 Spring Boot Starter 的工作原理。


二、什么是 Starter?

Starter 可以理解为一组 模块化依赖,它们帮助我们快速集成某种功能。

举个例子:

  • spring-boot-starter-web 会自动引入:

    • Spring MVC

    • Jackson JSON

    • Tomcat 依赖

      让我们可以直接写 @RestController 提供接口。

官方提供了大量 Starter(如 spring-boot-starter-data-jpa, spring-boot-starter-security),社区也有第三方 Starter,甚至可以编写 自定义 Starter


三、Starter 的核心原理

1. 自动配置核心注解

  • @EnableAutoConfiguration(通常通过 @SpringBootApplication 间接引入)

  • 作用:告诉 Spring Boot 根据类路径中的依赖和配置,自动装配 Bean

2. SPI 机制加载配置类

Spring Boot 使用 SpringFactoriesLoader 加载自动配置类:

  • 在每个 Starter 的 META-INF/spring.factories 文件中,会声明对应的自动配置类:

    XML 复制代码
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
    org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

2.7.18版本里

XML 复制代码
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer

# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.autoconfigure.integration.IntegrationPropertiesEnvironmentPostProcessor

# Auto Configuration Import Listeners
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener

# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
org.springframework.boot.autoconfigure.condition.OnClassCondition,\
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition

# Failure analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.autoconfigure.data.redis.RedisUrlSyntaxFailureAnalyzer,\
org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\
org.springframework.boot.autoconfigure.flyway.FlywayMigrationScriptMissingFailureAnalyzer,\
org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,\
org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer,\
org.springframework.boot.autoconfigure.jooq.NoDslContextBeanFailureAnalyzer,\
org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryBeanCreationFailureAnalyzer,\
org.springframework.boot.autoconfigure.r2dbc.MissingR2dbcPoolDependencyFailureAnalyzer,\
org.springframework.boot.autoconfigure.r2dbc.MultipleConnectionPoolConfigurationsFailureAnalyzer,\
org.springframework.boot.autoconfigure.r2dbc.NoConnectionFactoryBeanFailureAnalyzer,\
org.springframework.boot.autoconfigure.session.NonUniqueSessionRepositoryFailureAnalyzer

# Template availability providers
org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.web.servlet.JspTemplateAvailabilityProvider

# DataSource initializer detectors
org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector=\
org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializerDatabaseInitializerDetector

# Depends on database initialization detectors
org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector=\
org.springframework.boot.autoconfigure.batch.JobRepositoryDependsOnDatabaseInitializationDetector,\
org.springframework.boot.autoconfigure.quartz.SchedulerDependsOnDatabaseInitializationDetector,\
org.springframework.boot.autoconfigure.session.JdbcIndexedSessionRepositoryDependsOnDatabaseInitializationDetector
  • Spring Boot 启动时,会扫描 spring.factories,找到所有 EnableAutoConfiguration 的实现类并加载。

3. 条件注解控制生效

Starter 的自动配置并不是"强制开启",而是通过 条件注解 控制:

  • @ConditionalOnClass:当某个类在 classpath 中存在时才生效

  • @ConditionalOnMissingBean:当容器中不存在指定 Bean 时才生效

  • @ConditionalOnProperty:当配置文件中存在某个属性时才生效

例如:
WebMvcAutoConfiguration 只有在 DispatcherServlet 存在时才会生效。


四、源码执行流程

spring-boot-starter-web 为例:

  1. 引入 Starter

    pom.xml 中添加:

    复制代码
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  2. 依赖加载

    Maven 会拉取 Spring MVC、Jackson、Tomcat 等依赖。

  3. 扫描自动配置类

    启动时,Spring Boot 扫描 spring.factories,发现 WebMvcAutoConfiguration

  4. 条件匹配

    判断 classpath 中是否存在 DispatcherServlet,以及用户是否手动定义了 WebMvcConfigurer

  5. 自动装配生效

    若条件满足,Spring Boot 自动注册 RequestMappingHandlerMappingMessageConverter 等 Bean。


五、自定义 Starter 实战

假设我们要封装一个 HelloService Starter,只需三步:

1. 定义服务类

复制代码
public class HelloService {
    private String name;

    public HelloService(String name) {
        this.name = name;
    }

    public String sayHello() {
        return "Hello, " + name + "!";
    }
}

2. 编写自动配置类

复制代码
@Configuration
@ConditionalOnClass(HelloService.class)
@EnableConfigurationProperties(HelloProperties.class)
public class HelloAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public HelloService helloService(HelloProperties properties) {
        return new HelloService(properties.getName());
    }
}

3. 配置 spring.factories

resources/META-INF/spring.factories

复制代码
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autoconfig.HelloAutoConfiguration

4. 使用方式

  • 引入 hello-spring-boot-starter

  • application.yml 配置:

    复制代码
    hello:
      name: ChatGPT
  • 在项目中直接调用:

    复制代码
    @Autowired
    private HelloService helloService;
    
    System.out.println(helloService.sayHello()); // Hello, ChatGPT!

这样,一个 自定义 Starter 就完成了。


六、常见面试问题

  1. Spring Boot Starter 的本质是什么?

    • 一组依赖 + 自动配置类。
  2. Spring Boot 如何加载 Starter 的自动配置?

    • 通过 spring.factoriesSpringFactoriesLoader
  3. 如何防止 Starter 与用户配置冲突?

    • 使用条件注解,比如 @ConditionalOnMissingBean
  4. 如何编写一个自定义 Starter?

    • 提供自动配置类

    • 定义 spring.factories

    • 打包为依赖即可。


七、总结

Spring Boot Starter 本质上是 依赖管理 + 自动配置 的组合,它极大降低了上手门槛。通过 SPI + 条件注解 ,实现了灵活可控的 Bean 装配。

掌握 Starter 的原理和自定义方法,不仅能帮助我们理解 Spring Boot 内部机制,还能让我们在实际项目中封装通用模块,提升开发效率。


👉 推荐阅读方向:

  • 深入研究 SpringFactoriesLoader 源码

  • 探索 @Conditional 系列注解

  • 实战封装企业级 Starter(如统一日志、监控、缓存)

相关推荐
座山雕~1 分钟前
测试接口-----详细
开发语言·postman
拾忆,想起7 分钟前
TCP滑动窗口:网络世界的“智能流量阀门”
java·网络·数据库·网络协议·tcp/ip·php·哈希算法
小龙报11 分钟前
算法通关指南:数据结构和算法篇 --- 队列相关算法题》--- 1. 【模板】队列,2. 机器翻译
c语言·开发语言·数据结构·c++·算法·学习方法·visual studio
摇滚侠12 分钟前
Spring Boot3零基础教程,Reactive-Stream 发布订阅写法,笔记104 笔记105
java·spring boot·笔记
木木em哈哈18 分钟前
有关于cnb自动化的脚本补全
服务器·开发语言·pygame
星释19 分钟前
Rust 练习册 :Poker与扑克牌游戏
开发语言·游戏·rust
晨非辰28 分钟前
【数据结构初阶】--从排序算法原理分析到代码实现操作,参透插入排序的奥秘!
c语言·开发语言·数据结构·c++·算法·面试·排序算法
Jonathan Star33 分钟前
Next.js、NestJS、Nuxt.js 是 **Node.js 生态中针对不同场景的框架**
开发语言·javascript·node.js
laplace01233 小时前
Java八股—MySQL
java·mysql·oracle
zhangyao9403303 小时前
关于js导入Excel时,Excel的(年/月/日)日期是五位数字的问题。以及对Excel日期存在的错误的分析和处理。
开发语言·javascript·excel