欢迎光临小站:致橡树
Spring Boot Starter 的核心设计理念是 约定优于配置,其核心实现基于 自动配置(Auto-Configuration) 和 条件化注册(Conditional Registration)。以下是其生效原理:
约定大于配置
通过预定义合理的默认行为和规范,减少开发者需要手动配置的步骤。比较显著的变化就是减少XML配置。还有一些实际体现如下所示:
-
项目结构约定
-
默认目录结构:如
src/main/java
存放代码,src/main/resources
存放配置文件。 -
配置文件命名:
application.properties
或application.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!