SpringBoot Starter 依赖相关总结

Spring Boot Starter 依赖相关总结

一、Starter 的本质:约定优于配置的工程化产物

Starter 是一种「依赖聚合 + 自动配置」的打包规范。

它的核心思想是:把某一类功能所需的所有依赖、默认配置、自动装配逻辑,打包成一个可插拔的模块。开发者只需引入一个 starter,就能获得完整的功能能力。


二、Starter 解决了什么痛点

在没有 Starter 的传统 Spring 项目中,集成一个中间件(如 MyBatis)需要:

xml 复制代码
<!-- 1. 引入核心依赖 -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.9</version>
</dependency>

<!-- 2. 引入 Spring 整合包 -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.7</version>
</dependency>

<!-- 3. 引入数据库驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.30</version>
</dependency>

<!-- 4. 引入连接池 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.11</version>
</dependency>

<!-- 5. 手写大量 XML / JavaConfig 配置 -->

注:mysql:mysql-connector-java 在 8.0.31 之后已迁移为 com.mysql:mysql-connector-j,新项目用新坐标。

有了 Starter 之后:

xml 复制代码
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.2</version>
</dependency>

一行搞定所有依赖 + 自动配置。这就是 Starter 的价值。


三、Starter 的命名规范

类型 命名格式 示例
官方 Starter spring-boot-starter-* spring-boot-starter-web
第三方 Starter *-spring-boot-starter mybatis-spring-boot-starter
自定义 Starter *-spring-boot-starter mycompany-redis-spring-boot-starter

⚠️ 官方独占 spring-boot-starter- 前缀,第三方和自定义必须用 *-spring-boot-starter 后缀,这是社区约定。


四、Starter 的内部结构:双模块设计

一个规范的 Starter 通常由两个子模块组成:

text 复制代码
my-starter/
├── my-spring-boot-starter/          # ① 空壳 starter(仅负责依赖聚合)
│   └── pom.xml  → 引入 autoconfigure + 第三方依赖
│
└── my-spring-boot-autoconfigure/    # ② 自动配置模块(核心逻辑)
    ├── pom.xml
    └── src/main/java/
        ├── MyAutoConfiguration.java    # @AutoConfiguration
        ├── MyProperties.java           # @ConfigurationProperties
        └── META-INF/
            ├── spring.factories          # Spring Boot 2.7 之前
            └── org.springframework.boot.autoconfigure.AutoConfiguration.imports  # 2.7+

为什么拆成两个模块?

  • starter 模块:只做依赖聚合,无代码逻辑,让使用者引入即可
  • autoconfigure 模块:包含自动配置类、条件注解、属性绑定等核心逻辑

这种解耦的好处:如果用户不想用自动配置,可以只引 autoconfigure 模块,手动装配。


五、自动配置的核心机制

5.1 前置:@AutoConfiguration@Configuration 的区别

自动配置类现在用 @AutoConfiguration(2.7+),但它和普通 @Configuration 还是有差异的:

对比项 @Configuration @AutoConfiguration
用途 普通业务配置类 专用于自动配置类
发现方式 @ComponentScan 组件扫描 imports 文件加载(官方约定不靠扫描)
排序控制 支持 after / before 属性
Bean 方法代理 proxyBeanMethods=true(默认) proxyBeanMethods=false(默认)

要点:

  • @AutoConfiguration 本质是 @Configuration(proxyBeanMethods = false)组合注解 ,额外支持 after/before 排序。
  • proxyBeanMethods = false:不代理 @Bean 方法,更轻量------自动配置类里 Bean 之间通常不互相调用,不需要代理。
  • 2.7 之前自动配置类用 @Configuration + spring.factories 注册;2.7 起推荐 @AutoConfiguration + imports 文件。
  • 补充:@AutoConfiguration 也组合了 @Configuration(进而 @Component),理论上能被扫描到;但官方约定自动配置类不靠组件扫描、而靠 imports 文件加载(且它们通常位于扫描路径之外)。

5.2 入口:注册文件(spring.factoriesAutoConfiguration.imports

Spring Boot 启动时扫描 classpath 下的注册文件,加载自动配置类。

精确时间线:

版本 机制
2.7 之前 只认 META-INF/spring.factories 里的 EnableAutoConfiguration
2.7 引入 META-INF/spring/...AutoConfiguration.imports两者兼容(spring.factories 标记废弃)
3.0 彻底移除spring.factories 自动配置的支持,只认 imports 文件
properties 复制代码
# 2.7 之前:META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyAutoConfiguration
text 复制代码
# 2.7+ / 3.x:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.example.MyAutoConfiguration

注意:spring.factories 文件本身没废弃(还用于 ApplicationListenerEnvironmentPostProcessor 等),只是"自动配置注册"这一项迁移走了。

5.3 条件装配:@Conditional 家族

自动配置类不会无条件生效,而是通过条件注解控制:

java 复制代码
@AutoConfiguration
@ConditionalOnClass(DataSource.class)              // classpath 有 DataSource 才生效
@ConditionalOnProperty(prefix = "my.datasource", name = "enabled", havingValue = "true", matchIfMissing = true)
@EnableConfigurationProperties(MyProperties.class)
public class MyDataSourceAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean(DataSource.class)   // 用户没自定义时才创建
    public DataSource dataSource(MyProperties props) {
        return new HikariDataSource();
    }
}

常用条件注解:

注解 作用
@ConditionalOnClass classpath 存在某类时生效
@ConditionalOnMissingClass classpath 不存在某类时生效
@ConditionalOnBean 容器中存在某 Bean 时生效
@ConditionalOnMissingBean 容器中不存在某 Bean 时生效
@ConditionalOnProperty 配置文件中某属性满足条件时生效
@ConditionalOnWebApplication 是 Web 应用时生效

细节:@ConditionalOnMissingBean 不带参数时,默认按方法返回类型匹配(容器里没有该类型的 Bean 才创建)。

5.4 属性绑定:@ConfigurationProperties 的三种注册方式

java 复制代码
@ConfigurationProperties(prefix = "my.datasource")
@Data
public class MyProperties {
    private String url;
    private String username;
    private String password;
    private int maxConnections = 10;  // 默认值
}

要让上面的属性类真正生效(被绑定),有三种注册方式:

  1. @EnableConfigurationProperties(MyProperties.class) ------ 显式声明(最常用,推荐
  2. @ConfigurationPropertiesScan ------ 扫描包下所有 @ConfigurationProperties
  3. @Component + @ConfigurationProperties ------ 直接把属性类注册成组件

5.5 自动配置排序(多 starter 协作的关键)

多个自动配置类之间常有依赖关系,必须控制加载顺序:

java 复制代码
@AutoConfiguration
@AutoConfigureAfter(DataSourceAutoConfiguration.class)   // 在它之后加载
@AutoConfigureBefore(SecurityAutoConfiguration.class)    // 在它之前加载
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)          // 或直接定顺序
@ConditionalOnClass(RedisClient.class)
@EnableConfigurationProperties(MyRedisProperties.class)
public class MyRedisAutoConfiguration {
    // ...
}

为什么需要排序?比如你的自动配置要注入一个 DataSource Bean,那就必须 @AutoConfigureAfter(DataSourceAutoConfiguration.class),否则 DataSource 还没创建、注入就失败了。


六、自定义 Starter 的完整步骤

假设我们要做一个 my-redis-spring-boot-starter

Step 1:创建 autoconfigure 模块

java 复制代码
// MyRedisAutoConfiguration.java
@AutoConfiguration
@ConditionalOnClass(RedisClient.class)
@EnableConfigurationProperties(MyRedisProperties.class)
public class MyRedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public RedisClient redisClient(MyRedisProperties props) {
        return new RedisClient(props.getHost(), props.getPort());
    }
}
java 复制代码
// MyRedisProperties.java
@ConfigurationProperties(prefix = "my.redis")
@Data
public class MyRedisProperties {
    private String host = "localhost";
    private int port = 6379;
}

Step 2:创建 starter 模块(空壳)

xml 复制代码
<!-- my-redis-spring-boot-starter/pom.xml -->
<dependencies>
    <dependency>
        <groupId>com.example</groupId>
        <artifactId>my-redis-spring-boot-autoconfigure</artifactId>
    </dependency>
    <dependency>
        <groupId>io.lettuce</groupId>
        <artifactId>lettuce-core</artifactId>
    </dependency>
</dependencies>

Step 3:注册自动配置类

text 复制代码
# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.example.redis.MyRedisAutoConfiguration

Step 4:使用

xml 复制代码
<dependency>
    <groupId>com.example</groupId>
    <artifactId>my-redis-spring-boot-starter</artifactId>
    <version>1.0.0</version>
</dependency>
yaml 复制代码
my:
  redis:
    host: 192.168.1.100
    port: 6380

Step 5(可选但推荐):生成配置元数据 metadata

规范的 starter 会提供配置元数据,让 IDE 在 application.yml 里写 my.redis. 时能自动补全、提示类型和默认值。

引入注解处理器(编译期自动从 @ConfigurationProperties 生成元数据):

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

编译后自动生成 META-INF/spring-configuration-metadata.json(也可手写 additional-spring-configuration-metadata.json 补充):

json 复制代码
{
  "properties": [
    {
      "name": "my.redis.host",
      "type": "java.lang.String",
      "description": "Redis 地址",
      "defaultValue": "localhost"
    },
    {
      "name": "my.redis.port",
      "type": "java.lang.Integer",
      "defaultValue": 6379
    }
  ]
}

七、常见官方 Starter 速查

Starter 功能
spring-boot-starter-web Web 开发(Tomcat + Spring MVC)
spring-boot-starter-webflux 响应式 Web(Netty + WebFlux)
spring-boot-starter-data-jpa JPA 数据访问
spring-boot-starter-data-redis Redis 操作
spring-boot-starter-security 安全认证
spring-boot-starter-test 测试支持(JUnit + Mockito)
spring-boot-starter-actuator 监控端点
spring-boot-starter-amqp RabbitMQ
spring-boot-starter-mail 邮件发送

八、使用 Starter 的注意事项

  1. 版本管理交给 parent POM :官方 starter 的版本由 spring-boot-starter-parent 统一管理,不要手动指定版本(第三方除外)。
  2. 排除不需要的依赖 :starter 可能引入你不需要的传递依赖,用 <exclusions> 排除。
  3. 自定义配置覆盖默认值 :通过 application.yml 修改属性,或通过 @Bean 覆盖自动配置的 Bean。
  4. 关闭某个自动配置
java 复制代码
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
  1. Spring Boot 2.7 / 3.0 的注册方式变化 :自动配置从 spring.factories 迁移到 imports 文件(2.7 引入、3.0 彻底移除),自定义 starter 需注意兼容性。

九、总结

Starter = 依赖聚合(pom)+ 自动装配(@AutoConfiguration + 条件注解 + 属性绑定)+ 约定优于配置。

它是 Spring Boot「开箱即用」哲学的核心载体,理解 Starter 就是理解 Spring Boot 的自动配置体系。

相关推荐
吴声子夜歌1 小时前
Java面试——Spring Cloud原理及应用(二)
java·spring cloud·面试
东小西2 小时前
【SAA实战】第 1 篇:ReactAgent 入门——先撸个"会调工具的助手"跑起来
java·人工智能·spring
mqiqe3 小时前
AgentScope Java 2.0 协议集成全景解析:A2A、AG-UI、Agent Protocol 三大开放协议实战指南
java·开发语言·ui
脉动数据行情3 小时前
Java 实现台股 TWSE/TPEx 行情采集(个股 + K 线)
java·开发语言·twse·tpex·台股
月华路5 小时前
G1 GC 对数组与大对象(Humongous)的处理
java·jvm·算法
liangshanbo12155 小时前
虚拟列表深度面试题整理
java·开发语言·前端
gugucoding5 小时前
59. 【Java】Spring Boot 入门:第一个 Web 应用
java·开发语言·spring boot
10mAh6 小时前
【Java】HashMap 的 put 到底做了什么?——冲突、扩容与树化实测
java·开发语言·hash
我命由我123457 小时前
人脸识别 - 勒克斯(光线照射到物体表面上的明亮程度)
android·java·学习·java-ee·人脸识别·学习方法·android runtime