Spring Boot Starter 自动装配原理全解析
作者:葵续浅笑
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.properties或application.yml自动被加载,无需显式指定路径。
- 默认目录结构:如
- 自动配置(Auto-Configuration)
- 条件化 Bean 注册:根据类路径依赖(如存在
DataSource类)自动配置数据库连接池。 - 默认参数值:如嵌入式 Tomcat 默认端口为
8080,无需手动指定。
- 条件化 Bean 注册:根据类路径依赖(如存在
- 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 自动装配内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
您可能感兴趣的文章:
- Spring Boot 自动装配原理及 Starter 实现原理解析
- SpringBoot详细分析自动装配原理并实现starter
- SpringBoot多数据源解决方案:dynamic-datasource-spring-boot-starter
- SpringBoot利用dynamic-datasource-spring-boot-starter解决多数据源问题
- 解决mybatis-plus-boot-starter与mybatis-spring-boot-starter的错误问题
- Springboot整合spring-boot-starter-data-elasticsearch的过程
- SpringBoot的父级依赖:spring-boot-starter-parent详解
