【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
文件中,会声明对应的自动配置类:org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
2.7.18版本里
# 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
为例:
引入 Starter
在pom.xml
中添加:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency>
依赖加载
Maven 会拉取 Spring MVC、Jackson、Tomcat 等依赖。扫描自动配置类
启动时,Spring Boot 扫描spring.factories
,发现WebMvcAutoConfiguration
。条件匹配
判断 classpath 中是否存在DispatcherServlet
,以及用户是否手动定义了WebMvcConfigurer
。自动装配生效
若条件满足,Spring Boot 自动注册RequestMappingHandlerMapping
、MessageConverter
等 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@ConditionalOnMissingBeanpublic 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 就完成了。
六、常见面试问题
Spring Boot Starter 的本质是什么?
一组依赖 + 自动配置类。
Spring Boot 如何加载 Starter 的自动配置?
通过
spring.factories
和SpringFactoriesLoader
。
如何防止 Starter 与用户配置冲突?
使用条件注解,比如
@ConditionalOnMissingBean
。
如何编写一个自定义 Starter?
提供自动配置类
定义
spring.factories
打包为依赖即可。
七、总结
Spring Boot Starter 本质上是 依赖管理 + 自动配置 的组合,它极大降低了上手门槛。通过 SPI + 条件注解,实现了灵活可控的 Bean 装配。
掌握 Starter 的原理和自定义方法,不仅能帮助我们理解 Spring Boot 内部机制,还能让我们在实际项目中封装通用模块,提升开发效率。
👉 推荐阅读方向:
深入研究
SpringFactoriesLoader
源码探索
@Conditional
系列注解实战封装企业级 Starter(如统一日志、监控、缓存)