SpringBoot 核心原理:起步依赖与自动配置
一、起步依赖(Starter Dependency)
1. 核心本质
基于 Maven 依赖传递,SpringBoot 将某一场景(如 Web、数据源)所需的所有依赖(核心 Jar、第三方依赖)打包为「starter」模块,引入一个 starter 即可自动下载所有相关依赖,无需手动逐个引入。
2. 核心特点
-
场景化:一个 starter 对应一个功能(例:
spring-boot-starter-web对应 Web 开发)。 -
版本统一:父工程
spring-boot-starter-parent管理所有依赖版本,避免冲突。 -
依赖透明:引入 starter 后,Maven 自动解析传递依赖(例:
spring-boot-starter-web自动包含spring-web、tomcat-embed-core)。
二、自动配置(AutoConfiguration)
1. 核心目标
启动后自动将场景所需 Bean(如 DispatcherServlet、DataSource)加载到 IOC 容器,无需手动写配置类。
2. 核心流程
-
启动类触发:
@SpringBootApplication是组合注解,核心是@EnableAutoConfiguration(自动配置开关)+@ComponentScan(扫描自定义 Bean)。其中重点为
@EnableAutoConfiguration,见后述详叙。 -
筛选配置类:通过
@Conditional注解筛选当前环境需要的自动配置类。 -
注入容器:将筛选后有效的配置类中的
@Bean自动注入 IOC 容器。
3. 配置优先级(从高到低)
-
命令行参数(
java -jar app.jar --server.port=8081) -
环境变量(
SERVER_PORT=8081) -
配置文件(
application.yml/properties) -
自动配置默认值(优先级最低)
三、@EnableAutoConfiguration 深度解析
1. 核心作用
开启自动配置,让 Spring 主动加载外部 Jar 包中的配置类(解决传统 Spring 无法扫描外部 Bean 的问题)。
内含两个关键注解:
@AutoConfigurationPackage:将主启动类所在包注册为扫描包,确保自定义 Bean能被发现。@Import(AutoConfigurationImportSelector.class):见下述详叙。
2. 底层原理(3 步)
-
导入处理器:通过
@Import(AutoConfigurationImportSelector.class)触发配置类扫描。补充:
@Import导入形式主要有 3 种,AutoConfigurationImportSelector属于第三种:-
导入普通类:直接注册为 IOC Bean;
-
导入配置类:其内部
@Bean会被注册为 IOC Bean; -
导入
ImportSelector接口实现类(如AutoConfigurationImportSelector):-
需实现
String[] selectImports(AnnotationMetadata importingClassMetadata)方法; -
参数
importingClassMetadata:获取标注@Import的类的元数据(如注解、类名),用于动态判断; -
返回值
String[]:要导入的类的全路径数组,Spring 会自动注册为 Bean。
-
-
-
读取候选配置:
AutoConfigurationImportSelector实现类从指定文件读取所有候选自动配置类:-
SpringBoot 2.7+:
META-INF/spring /org.springframework.boot.autoconfigure.AutoConfiguration.imports(纯文本,每行一个类名) -
2.7 之前:
META-INF/spring.factories(Properties 格式,key 为EnableAutoConfiguration)
-
-
筛选有效配置后封装成String[]返回要导入的类的全路径数组:
- 条件筛选:通过
@Conditional派生注解按需筛选,常用注解如下:
| 注解 | 生效条件 | 典型场景 |
|---|---|---|
@ConditionalOnClass | 类路径中存在指定类 | 引入对应 starter 后才生效(如 spring-webmvc 存在则加载 Web 配置) |
@ConditionalOnMissingClass | 类路径中不存在指定类 | 兼容低版本依赖,避免冲突 |
@ConditionalOnBean | IOC 容器中已存在指定 Bean | 依赖其他 Bean 才能生效(如需 DataSource 才加载 JdbcTemplate) |
@ConditionalOnMissingBean | IOC 容器中不存在指定 Bean | 开发者自定义 Bean 优先(如手动声明 RestTemplate 则覆盖自动配置) |
@ConditionalOnProperty | 配置文件中存在指定属性(支持匹配值) | spring.cache.type=redis 才加载 Redis 缓存配置 |
@ConditionalOnWebApplication | 当前是 Web 应用(Servlet/Reactive) | WebMvcAutoConfiguration 仅在 Web 环境生效 |
- 手动排除:通过
@SpringBootApplication(exclude = 类名.class)排除不需要的配置类。
四、自定义 Starter 实战(阿里云 OSS 示例)
1. 模块拆分
-
aliyun-oss-spring-boot-starter:仅管理依赖,引入自动配置模块。 -
aliyun-oss-spring-boot-autoconfigure:实现自动配置逻辑。
2. 核心代码
- 配置属性类(读取
application.yml配置):
// 读取配置文件中前缀为aliyun.oss的配置
// 由于没有加入IOC容器,不能用@Component
// 需要在自动配置类上加@EnableConfigurationProperties(AliyunOSSProperties.class)
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliyunOSSProperties {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
// getter/setter
}
- 自动配置类:
@Configuration
@ConditionalOnClass(OSS.class) // 引入 OSS SDK 才生效
@EnableConfigurationProperties(AliyunOSSProperties.class)
public class AliyunOSSAutoConfiguration {
@Bean
@ConditionalOnMissingBean // 开发者自定义 Bean 优先
public OSS ossClient(AliyunOSSProperties properties) {
return new OSSClientBuilder().build(
properties.getEndpoint(),
properties.getAccessKeyId(),
properties.getAccessKeySecret()
);
}
@Bean
@ConditionalOnMissingBean
public AliyunOSSUtils aliyunOSSUtils(OSS ossClient, AliyunOSSProperties properties) {
return new AliyunOSSUtils(ossClient, properties.getBucketName());
}
}
- 关联自动配置:在
autoconfigure模块中创建META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,写入:
com.example.aliyun.oss.autoconfigure.AliyunOSSAutoConfiguration
3. 使用方式
-
引入依赖:添加
aliyun-oss-spring-boot-starter。 -
配置
application.yml:填写阿里云 OSS 信息。 -
直接注入
AliyunOSSUtils即可使用。
五、核心关系
-
起步依赖:提供自动配置所需的 Jar 包(满足
@ConditionalOnClass条件)。 -
自动配置:注入场景 Bean,二者结合实现「引入即用」。