Spring Boot Starter 自动装配原理全解析

 更新时间:2025年04月22日 09:53:38   作者:葵续浅笑  
Spring Boot Starter 的核心设计理念是 约定优于配置,其核心实现基于 自动配置(Auto-Configuration) 和 条件化注册(Conditional Registration),这篇文章主要介绍了Spring Boot Starter 自动装配原理全解析,需要的朋友可以参考下

Spring Boot Starter 的核心设计理念是 约定优于配置,其核心实现基于 自动配置(Auto-Configuration)条件化注册(Conditional Registration)。以下是其生效原理:

约定大于配置

通过预定义合理的默认行为和规范,减少开发者需要手动配置的步骤。比较显著的变化就是减少XML配置。还有一些实际体现如下所示:

  • 项目结构约定
    • 默认目录结构:如 src/main/java 存放代码,src/main/resources 存放配置文件。
    • 配置文件命名application.propertiesapplication.yml 自动被加载,无需显式指定路径。
  • 自动配置(Auto-Configuration)
    • 条件化 Bean 注册:根据类路径依赖(如存在 DataSource 类)自动配置数据库连接池
    • 默认参数值:如嵌入式 Tomcat 默认端口为 8080,无需手动指定。
  • Starter 依赖
    • 依赖聚合:引入 spring-boot-starter-web 即自动包含 Web 开发所需的所有依赖(如 Tomcat、Jackson、Spring MVC)。
    • 开箱即用:无需手动管理版本兼容性。
  • RESTful 路由映射
    • 注解驱动:通过 @GetMapping("/path") 即可定义接口,无需在 XML 中配置路由规则。

自动配置机制

触发阶段:@EnableAutoConfiguration

  • 应用启动时,@SpringBootApplication 组合了 @EnableAutoConfiguration,触发自动配置流程。
  • AutoConfigurationImportSelector 被调用,负责加载所有候选的自动配置类。
public String[] selectImports(AnnotationMetadata metadata) {
  // 1. 加载所有候选自动配置类
  List<String> configurations = getCandidateConfigurations();
  // 2. 去重、过滤、排序
  configurations = removeDuplicates(configurations);
  configurations = filter(configurations, autoConfigurationMetadata);
  return configurations.toArray(new String[0]);
}

加载与筛选:spring.factories

  • 加载所有候选配置类

从所有 META-INF/spring.factories 文件中读取 EnableAutoConfiguration 对应的配置类。在 Spring Boot 3.x 中,自动配置类的加载方式从 spring.factories 过渡到 AutoConfiguration.imports,并引入了 ImportCandidates 类来处理这一变化。

  • 去重与过滤

移除重复的配置类,并通过条件注解(如 @ConditionalOnClass ,@ConditionalOnMissingBean ) 有选择的保留当前环境的配置类。

  • @ConditionalOnClass:类路径存在指定类时生效
  • @ConditionalOnMissingBean:容器中不存在指定 Bean 时生效
  • @ConditionalOnProperty:配置属性匹配时生效

排序

根据 @AutoConfigureOrder@AutoConfigureAfter 调整配置类的加载顺序。

Bean 注册

  • 筛选后的自动配置类被解析为标准的 @Configuration 类。
  • 每个配置类中的 @Bean 方法根据条件注解动态注册 Bean 到 Spring 容器。

编写自定义Spring Boot Starter

项目结构规划

建议分为两个模块:

  • 自动配置模块:包含核心逻辑和自动配置类(如 hello-spring-boot-autoconfigure)。
  • Starter模块:空项目,仅作为依赖聚合(如 hello-spring-boot-starter)。
hello-spring-boot-starter-parent(父POM)
├── hello-spring-boot-autoconfigure(自动配置模块)
└── hello-spring-boot-starter(Starter模块)
hello-spring-boot-starter/
├── hello-spring-boot-autoconfigure/
│   ├── src/
│   │   ├── main/
│   │   │   ├── java/com/example/autoconfigure/
│   │   │   │   ├── HelloAutoConfiguration.java
│   │   │   │   ├── HelloProperties.java
│   │   │   │   └── HelloService.java
│   │   │   └── resources/
│   │   │       └── META-INF/
│   │   │           └── spring.factories
│   │   └── test/
│   └── pom.xml
├── hello-spring-boot-starter/
│   └── pom.xml
└── pom.xml

创建自动配置模块(hello-spring-boot-autoconfigure)

添加Maven依赖

<!-- pom.xml -->
<dependencies>
    <!-- Spring Boot 自动配置基础依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-autoconfigure</artifactId>
        <version>3.1.5</version>
    </dependency>
    <!-- 可选:配置属性处理 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <version>3.1.5</version>
        <optional>true</optional>
    </dependency>
</dependencies>

定义核心服务类

public class HelloService {
    private String message = "Hello, World!";  // 默认消息
    public String sayHello() {
        return message;
    }
    // Getter和Setter用于通过配置修改message
    public String getMessage() { return message; }
    public void setMessage(String message) { this.message = message; }
}

定义配置属性类(可选)

@ConfigurationProperties(prefix = "hello")
public class HelloProperties {
    private String message = "Hello, World!";
    // Getter和Setter
    public String getMessage() { return message; }
    public void setMessage(String message) { this.message = message; }
}

编写自动配置类

@Configuration
@EnableConfigurationProperties(HelloProperties.class)  // 启用配置属性
@ConditionalOnClass(HelloService.class)  // 当HelloService在类路径时生效
public class HelloAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean  // 当用户未自定义HelloService时生效
    public HelloService helloService(HelloProperties properties) {
        HelloService service = new HelloService();
        service.setMessage(properties.getMessage());
        return service;
    }
}

注册自动配置

resources/META-INF/ 下创建 spring.factories 文件:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autoconfigure.HelloAutoConfiguration

创建Starter模块(hello-spring-boot-starter)

添加Maven依赖

<!-- pom.xml -->
<dependencies>
    <!-- 引入自动配置模块 -->
    <dependency>
        <groupId>com.example</groupId>
        <artifactId>hello-spring-boot-autoconfigure</artifactId>
        <version>1.0.0</version>
    </dependency>
</dependencies>

使用自定义Starter

在应用中引入Starter依赖

<!-- 用户项目的pom.xml -->
<dependency>
    <groupId>com.example</groupId>
    <artifactId>hello-spring-boot-starter</artifactId>
    <version>1.0.0</version>
</dependency>

在代码中注入Bean

@RestController
public class HelloController {
    @Autowired
    private HelloService helloService;
    @GetMapping("/hello")
    public String hello() {
        return helloService.sayHello();
    }
}

自定义配置(可选)

application.properties 中修改消息:

hello.message=你好, Spring Boot!

到此这篇关于Spring Boot Starter 自动装配原理的文章就介绍到这了,更多相关Spring Boot Starter 自动装配内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot2.x集成Dozer的示例代码

    SpringBoot2.x集成Dozer的示例代码

    本文主要介绍了SpringBoot2.x集成Dozer的示例代码,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • Java 设计模式以虹猫蓝兔的故事讲解简单工厂模式

    Java 设计模式以虹猫蓝兔的故事讲解简单工厂模式

    简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现
    2022-03-03
  • MybatisPlus之时间处理问题

    MybatisPlus之时间处理问题

    在数据库设计时,阿里巴巴编码规约建议使用gmt_create和gmt_modified命名时间字段,并设置为datetime类型,本文介绍了两种自动填充时间字段的实现方式:SQL级别和代码级别(使用MyBatis Plus),SQL级别通过设置默认值和更新值为CURRENT_TIMESTAMP
    2024-09-09
  • 详解Java停止线程的四种方法

    详解Java停止线程的四种方法

    如何停止java的线程一直是一个困恼我们开发多线程程序的一个问题吗,本文主要介绍了详解Java停止线程的四种方法,感兴趣的可以了解一下
    2021-05-05
  • Java二维数组实战案例

    Java二维数组实战案例

    这篇文章主要介绍了Java二维数组,结合具体案例形式分析了java二维数组定义、遍历、计算等相关操作技巧,需要的朋友可以参考下
    2019-08-08
  • 如何理解SpringMVC

    如何理解SpringMVC

    Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发
    2021-06-06
  • javaSE泛型、反射与注解的核心原理与实际应用

    javaSE泛型、反射与注解的核心原理与实际应用

    在日常开发中,必不可少的会使用到泛型,这篇文章主要介绍了javaSE泛型、反射与注解的核心原理与实际应用的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-08-08
  • Java经典设计模式之适配器模式原理与用法详解

    Java经典设计模式之适配器模式原理与用法详解

    这篇文章主要介绍了Java经典设计模式之适配器模式,简单说明了适配器模式的概念、原理,并结合实例形式分析了java适配器模式的用法与相关注意事项,需要的朋友可以参考下
    2017-08-08
  • Java效率提升神器jOOR

    Java效率提升神器jOOR

    这篇文章主要介绍了Java效率提升神器jOOR,jOOR是一个第三方库,通过链式DSL接口,简化了反射过程,更多相关内容组要的朋友可以参考一下
    2022-07-07
  • java实现猜拳小游戏

    java实现猜拳小游戏

    这篇文章主要为大家详细介绍了java实现猜拳小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-01-01

最新评论