SpringBoot 原理:起步依赖与自动配置

56 阅读4分钟

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-webtomcat-embed-core)。


二、自动配置(AutoConfiguration)

1. 核心目标

启动后自动将场景所需 Bean(如 DispatcherServletDataSource)加载到 IOC 容器,无需手动写配置类。

2. 核心流程
  1. 启动类触发@SpringBootApplication 是组合注解,核心是 @EnableAutoConfiguration(自动配置开关)+ @ComponentScan(扫描自定义 Bean)。

    其中重点为@EnableAutoConfiguration,见后述详叙。

  2. 筛选配置类:通过 @Conditional 注解筛选当前环境需要的自动配置类。

  3. 注入容器:将筛选后有效的配置类中的 @Bean 自动注入 IOC 容器。

3. 配置优先级(从高到低)
  1. 命令行参数(java -jar app.jar --server.port=8081

  2. 环境变量(SERVER_PORT=8081

  3. 配置文件(application.yml/properties

  4. 自动配置默认值(优先级最低)


三、@EnableAutoConfiguration 深度解析

1. 核心作用

开启自动配置,让 Spring 主动加载外部 Jar 包中的配置类(解决传统 Spring 无法扫描外部 Bean 的问题)。

内含两个关键注解:

  • @AutoConfigurationPackage:将主启动类所在包注册为扫描包,确保自定义 Bean能被发现。
  • @Import(AutoConfigurationImportSelector.class):见下述详叙。
2. 底层原理(3 步)
  1. 导入处理器:通过 @Import(AutoConfigurationImportSelector.class) 触发配置类扫描。

    补充:@Import 导入形式主要有 3 种,AutoConfigurationImportSelector 属于第三种:

    • 导入普通类:直接注册为 IOC Bean;

    • 导入配置类:其内部 @Bean 会被注册为 IOC Bean;

    • 导入 ImportSelector 接口实现类(如 AutoConfigurationImportSelector):

      • 需实现 String[] selectImports(AnnotationMetadata importingClassMetadata) 方法;

      • 参数 importingClassMetadata:获取标注 @Import 的类的元数据(如注解、类名),用于动态判断;

      • 返回值 String[]:要导入的类的全路径数组,Spring 会自动注册为 Bean。

  2. 读取候选配置AutoConfigurationImportSelector实现类从指定文件读取所有候选自动配置类:

    • SpringBoot 2.7+:META-INF/spring /org.springframework.boot.autoconfigure.AutoConfiguration.imports(纯文本,每行一个类名)

    • 2.7 之前:META-INF/spring.factories(Properties 格式,key 为 EnableAutoConfiguration

  3. 筛选有效配置后封装成String[]返回要导入的类的全路径数组

  • 条件筛选:通过 @Conditional 派生注解按需筛选,常用注解如下:
注解生效条件典型场景
@ConditionalOnClass类路径中存在指定类引入对应 starter 后才生效(如 spring-webmvc 存在则加载 Web 配置)
@ConditionalOnMissingClass类路径中不存在指定类兼容低版本依赖,避免冲突
@ConditionalOnBeanIOC 容器中已存在指定 Bean依赖其他 Bean 才能生效(如需 DataSource 才加载 JdbcTemplate
@ConditionalOnMissingBeanIOC 容器中不存在指定 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. 核心代码
  1. 配置属性类(读取 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

}
  1. 自动配置类
@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());
    }
}
  1. 关联自动配置:在 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,二者结合实现「引入即用」。