目录
- [🍃 38 Spring Boot入门------自动配置、核心注解与Starter机制](#🍃 38 Spring Boot入门——自动配置、核心注解与Starter机制)
-
- [一、Spring Boot概述](#一、Spring Boot概述)
-
- [1.1 为什么需要Spring Boot](#1.1 为什么需要Spring Boot)
- [1.2 Spring Boot核心特性](#1.2 Spring Boot核心特性)
- [1.3 Spring Boot与Spring的关系](#1.3 Spring Boot与Spring的关系)
- [二、快速创建Spring Boot项目](#二、快速创建Spring Boot项目)
-
- [2.1 使用Spring Initializr](#2.1 使用Spring Initializr)
- [2.2 Maven项目结构](#2.2 Maven项目结构)
- [2.3 pom.xml核心配置](#2.3 pom.xml核心配置)
- [2.4 启动类](#2.4 启动类)
- [2.5 第一个REST接口](#2.5 第一个REST接口)
- 三、核心注解详解
-
- [3.1 `@SpringBootApplication`](#3.1
@SpringBootApplication) - [3.2 Web层注解](#3.2 Web层注解)
- [3.3 依赖注入注解](#3.3 依赖注入注解)
- [3.4 配置相关注解](#3.4 配置相关注解)
- [3.1 `@SpringBootApplication`](#3.1
- 四、自动配置原理
-
- [4.1 自动配置流程](#4.1 自动配置流程)
- [4.2 `@Conditional`条件注解族](#4.2
@Conditional条件注解族) - [4.3 源码解析:以DataSource自动配置为例](#4.3 源码解析:以DataSource自动配置为例)
- [4.4 手动覆盖自动配置](#4.4 手动覆盖自动配置)
- [4.5 查看自动配置报告](#4.5 查看自动配置报告)
- 五、配置文件详解
-
- [5.1 两种配置文件格式](#5.1 两种配置文件格式)
- [5.2 配置文件加载优先级](#5.2 配置文件加载优先级)
- [5.3 自定义配置属性绑定](#5.3 自定义配置属性绑定)
- [5.4 类型安全的属性校验](#5.4 类型安全的属性校验)
- [5.5 复杂类型配置](#5.5 复杂类型配置)
- 六、多环境配置
-
- [6.1 多Profile文件](#6.1 多Profile文件)
- [6.2 激活Profile的多种方式](#6.2 激活Profile的多种方式)
- [6.3 Profile分组(Spring Boot 2.4+)](#6.3 Profile分组(Spring Boot 2.4+))
- [6.4 Profile条件装配](#6.4 Profile条件装配)
- 七、Starter机制
-
- [7.1 什么是Starter](#7.1 什么是Starter)
- [7.2 常用Starter一览](#7.2 常用Starter一览)
- [7.3 Starter的工作原理](#7.3 Starter的工作原理)
- [7.4 自定义Starter](#7.4 自定义Starter)
- [7.5 自定义Starter的最佳实践](#7.5 自定义Starter的最佳实践)
- [八、Spring Boot生命周期与扩展点](#八、Spring Boot生命周期与扩展点)
-
- [8.1 启动流程](#8.1 启动流程)
- [8.2 常用扩展点](#8.2 常用扩展点)
- [8.3 优雅关闭](#8.3 优雅关闭)
- 九、常见面试题解析
-
- [Q1:Spring Boot自动配置的原理是什么?](#Q1:Spring Boot自动配置的原理是什么?)
- Q2:`@SpringBootApplication`注解做了什么?
- [Q3:Spring Boot配置文件的加载优先级是怎样的?](#Q3:Spring Boot配置文件的加载优先级是怎样的?)
- Q4:Starter和普通依赖有什么区别?
- Q5:如何自定义Starter?
- 十、总结与下篇预告
🍃 38 Spring Boot入门------自动配置、核心注解与Starter机制
更新日期 :2026年6月 | Java入门到精通系列 · 第五阶段·企业级开发
© 版权声明:本文为原创技术文章,转载请联系作者并注明出处。
一、Spring Boot概述
1.1 为什么需要Spring Boot
在Spring Boot出现之前,搭建一个Spring Web应用需要大量的XML配置、依赖管理和环境搭建工作。一个简单的"Hello World"项目就需要:
- 配置
web.xml - 配置
applicationContext.xml - 配置Spring MVC的
DispatcherServlet - 管理几十个Maven依赖的版本兼容性
- 部署到外部Tomcat
Spring Boot 的核心理念是:约定优于配置(Convention over Configuration),让开发者用最少的配置快速启动一个Spring应用。
1.2 Spring Boot核心特性
| 特性 | 说明 | 解决的问题 |
|---|---|---|
| 自动配置 | 根据类路径自动推断并配置Bean | 消除大量XML配置 |
| Starter依赖 | 一站式依赖管理 | 解决版本冲突 |
| 内嵌服务器 | 内置Tomcat/Jetty/Undertow | 无需外部部署 |
| Actuator | 生产级监控端点 | 应用健康检查 |
| 配置文件 | 统一的application.yml |
配置管理标准化 |
| CLI工具 | 命令行快速开发 | 原型验证 |
1.3 Spring Boot与Spring的关系
┌──────────────────────────────────────────┐
│ Spring Boot │
│ ┌─────────────────────────────────────┐ │
│ │ 自动配置 (Auto-configuration) │ │
│ ├─────────────────────────────────────┤ │
│ │ Starter依赖 │ │
│ ├─────────────────────────────────────┤ │
│ │ ┌──────────────────────────────┐ │ │
│ │ │ Spring Framework │ │ │
│ │ │ ┌────────┐ ┌────────────┐ │ │ │
│ │ │ │ IoC │ │ AOP │ │ │ │
│ │ │ └────────┘ └────────────┘ │ │ │
│ │ │ ┌────────┐ ┌────────────┐ │ │ │
│ │ │ │ MVC │ │ Security │ │ │ │
│ │ │ └────────┘ └────────────┘ │ │ │
│ │ └──────────────────────────────┘ │ │
│ └─────────────────────────────────────┘ │
└──────────────────────────────────────────┘
Spring Boot 不是 Spring的替代品,而是Spring的脚手架,它建立在Spring Framework之上,简化了Spring应用的初始搭建和开发过程。
二、快速创建Spring Boot项目
2.1 使用Spring Initializr
最简单的方式是访问 start.spring.io 或在IDEA中创建:
推荐配置:
| 选项 | 推荐值 |
|---|---|
| Project | Maven |
| Language | Java |
| Spring Boot | 3.x(最新稳定版) |
| Group | com.example |
| Artifact | demo |
| Packaging | Jar |
| Java | 17+ |
2.2 Maven项目结构
demo/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/demo/
│ │ │ └── DemoApplication.java # 启动类
│ │ ├── resources/
│ │ │ ├── application.yml # 主配置文件
│ │ │ ├── application-dev.yml # 开发环境配置
│ │ │ ├── application-prod.yml # 生产环境配置
│ │ │ ├── static/ # 静态资源
│ │ │ └── templates/ # 模板文件
│ │ └── webapp/ # (可选)传统Web资源
│ └── test/
│ └── java/
│ └── com/example/demo/
│ └── DemoApplicationTests.java
├── pom.xml
└── mvnw / mvnw.cmd # Maven Wrapper
2.3 pom.xml核心配置
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 父级依赖:统一管理版本号 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Spring Boot Demo Project</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<!-- Web启动器:包含Spring MVC + 内嵌Tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 测试启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.4 启动类
java
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication // 核心注解,开启自动配置
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
运行main方法,一个Web应用就启动了,默认监听8080端口!
2.5 第一个REST接口
java
package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello, Spring Boot!";
}
}
访问 http://localhost:8080/hello 即可看到返回结果。
三、核心注解详解
3.1 @SpringBootApplication
这是Spring Boot最核心的注解,它是一个组合注解:
java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration // 标记为配置类
@EnableAutoConfiguration // 开启自动配置
@ComponentScan // 组件扫描
public @interface SpringBootApplication {
// ...
}
等价于以下三个注解的组合:
| 注解 | 作用 |
|---|---|
@SpringBootConfiguration |
标记当前类为配置类(本质是@Configuration) |
@EnableAutoConfiguration |
开启Spring Boot自动配置机制 |
@ComponentScan |
自动扫描当前包及子包下的组件 |
自定义扫描路径:
java
// 只扫描指定包
@SpringBootApplication(scanBasePackages = "com.example")
// 排除某些自动配置
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
3.2 Web层注解
java
@RestController // = @Controller + @ResponseBody,返回JSON
@Controller // MVC控制器,返回视图名称
@RequestMapping("/api") // 映射URL路径
@GetMapping("/users") // GET请求映射
@PostMapping("/users") // POST请求映射
@PutMapping("/{id}") // PUT请求映射
@DeleteMapping("/{id}") // DELETE请求映射
// 参数绑定注解
@PathVariable // URL路径变量 /users/{id}
@RequestParam // 查询参数 /users?page=1
@RequestBody // 请求体JSON绑定
@RequestHeader // 请求头绑定
3.3 依赖注入注解
java
@Component // 通用组件
@Service // 业务层
@Repository // 数据访问层
@Controller // 控制层
@Autowired // 按类型自动注入(字段注入,不推荐)
@RequiredArgsConstructor // Lombok:构造器注入(推荐方式)
@Inject // JSR-330标准注入
@Configuration // 配置类
@Bean // 配置类中定义Bean
@Scope // Bean作用域(singleton/prototype/request/session)
@Conditional // 条件装配
3.4 配置相关注解
java
@ConfigurationProperties(prefix = "app.mail") // 绑定配置文件属性
@Value("${app.name}") // 单个属性注入
@PropertySource("classpath:custom.properties") // 加载自定义配置文件
@Profile("dev") // 指定环境激活
四、自动配置原理
4.1 自动配置流程
Spring Boot的自动配置是其最核心的特性,整个流程如下:
启动
│
▼
@SpringBootApplication
│
├─ @EnableAutoConfiguration
│ │
│ ▼
│ Import AutoConfigurationImportSelector
│ │
│ ▼
│ 读取 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
│ │
│ ▼
│ 获取所有候选自动配置类(约100+个)
│ │
│ ▼
│ 根据 @Conditional 条件过滤
│ │
│ ▼
│ 满足条件的配置类生效,注册对应的Bean
│
▼
容器初始化完成
4.2 @Conditional条件注解族
| 注解 | 生效条件 |
|---|---|
@ConditionalOnClass |
类路径中存在指定类 |
@ConditionalOnMissingClass |
类路径中不存在指定类 |
@ConditionalOnBean |
容器中存在指定Bean |
@ConditionalOnMissingBean |
容器中不存在指定Bean(最常用,方便用户覆盖) |
@ConditionalOnProperty |
配置文件中指定属性有指定值 |
@ConditionalOnResource |
类路径下存在指定资源文件 |
@ConditionalOnWebApplication |
当前是Web应用 |
4.3 源码解析:以DataSource自动配置为例
java
@AutoConfiguration(before = SqlInitializationAutoConfiguration.class)
@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})
@ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory")
@EnableConfigurationProperties(DataSourceProperties.class)
@Import(DataSourcePoolMetadataProvidersConfiguration.class)
public class DataSourceAutoConfiguration {
// 嵌入式数据库(H2/HSQLDB/Derby)自动配置
@Configuration(proxyBeanMethods = false)
@Conditional(EmbeddedDatabaseCondition.class)
@ConditionalOnMissingBean({DataSource.class, XADataSource.class})
@Import(EmbeddedDataSourceConfiguration.class)
protected static class EmbeddedDatabaseConfiguration {
}
// 连接池(HikariCP/Tomcat/DBCP2)自动配置
@Configuration(proxyBeanMethods = false)
@Conditional(PooledDataSourceCondition.class)
@ConditionalOnMissingBean({DataSource.class, XADataSource.class})
@Import({DataSourceConfiguration.Hikari.class,
DataSourceConfiguration.Tomcat.class,
DataSourceConfiguration.Dbcp2.class})
protected static class PooledDataSourceConfiguration {
}
}
解读:
- 当类路径下存在
DataSource.class时,自动配置才生效 - 如果容器中还没有用户自定义的
DataSourceBean,则自动创建 - 优先使用HikariCP连接池(Spring Boot默认)
4.4 手动覆盖自动配置
java
@Configuration
public class CustomDataSourceConfig {
// 自定义Bean会覆盖自动配置的Bean
// 因为自动配置使用了 @ConditionalOnMissingBean
@Bean
public DataSource dataSource() {
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
ds.setUsername("root");
ds.setPassword("secret");
return ds;
}
}
4.5 查看自动配置报告
启动时添加 --debug 参数或配置 debug=true:
yaml
# application.yml
debug: true
启动后控制台会输出自动配置报告:
============================
CONDITIONS EVALUATION REPORT
============================
Positive matches:(生效的自动配置)
-----------------
DataSourceAutoConfiguration matched:
- @ConditionalOnClass found required classes 'javax.sql.DataSource',
'org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType'
Excluded exclusions:(被排除的)
--------------------
None
Unconditional classes:(无条件生效的)
----------------------
org.springframework.boot.autoconfigure.context...
五、配置文件详解
5.1 两种配置文件格式
Spring Boot支持两种配置文件格式:
application.properties(传统格式):
properties
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=123456
app.name=My Application
app.upload.max-size=10MB
application.yml(推荐,更清晰):
yaml
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: 123456
app:
name: My Application
upload:
max-size: 10MB
5.2 配置文件加载优先级
| 优先级 | 位置 | 说明 |
|---|---|---|
| 1(最高) | file:./config/ |
项目根目录的config子目录 |
| 2 | file:./ |
项目根目录 |
| 3 | classpath:/config/ |
类路径的config包 |
| 4(最低) | classpath:/ |
类路径根目录 |
高优先级配置会覆盖 低优先级配置,同时存在.properties和.yml时,.properties优先。
5.3 自定义配置属性绑定
方式一:@Value 注入单个值
java
@Component
public class AppInfo {
@Value("${app.name}")
private String appName;
@Value("${app.version:1.0.0}") // 带默认值
private String version;
@Value("${app.upload.max-size}")
private String maxSize;
}
方式二:@ConfigurationProperties 批量绑定(推荐)
yaml
# application.yml
app:
mail:
host: smtp.example.com
port: 587
username: admin@example.com
password: secret
protocol: smtp
default-encoding: UTF-8
java
@Data
@Component
@ConfigurationProperties(prefix = "app.mail")
public class MailProperties {
private String host;
private int port;
private String username;
private String password;
private String protocol;
private String defaultEncoding;
}
启用@ConfigurationProperties的第二种方式------@EnableConfigurationProperties:
java
@Data
@ConfigurationProperties(prefix = "app.mail") // 不加@Component
public class MailProperties {
private String host;
private int port;
}
// 在配置类中显式启用
@Configuration
@EnableConfigurationProperties(MailProperties.class)
public class MailConfig {
}
5.4 类型安全的属性校验
结合JSR-303验证注解:
java
@Data
@Component
@ConfigurationProperties(prefix = "app.mail")
@Validated
public class MailProperties {
@NotBlank(message = "邮件服务器地址不能为空")
private String host;
@Min(1)
@Max(65535)
private int port = 25; // 默认值
@Email
private String username;
@Pattern(regexp = "^(smtp|imap|pop3)$")
private String protocol = "smtp";
}
5.5 复杂类型配置
yaml
# application.yml
app:
servers:
- http://server1.example.com
- http://server2.example.com
- http://server3.example.com
security:
roles:
admin: "管理员权限"
user: "普通用户权限"
upload:
allowed-types:
- image/png
- image/jpeg
- application/pdf
java
@Data
@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private List<String> servers = new ArrayList<>();
private Map<String, String> security = new HashMap<>();
private Upload upload = new Upload();
@Data
public static class Upload {
private List<String> allowedTypes = new ArrayList<>();
}
}
六、多环境配置
6.1 多Profile文件
创建多个配置文件来管理不同环境:
resources/
├── application.yml # 公共配置
├── application-dev.yml # 开发环境
├── application-test.yml # 测试环境
├── application-staging.yml # 预发布环境
└── application-prod.yml # 生产环境
公共配置 application.yml:
yaml
app:
name: My Application
spring:
profiles:
active: dev # 默认激活的环境
开发环境 application-dev.yml:
yaml
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/dev_db
username: dev_user
password: dev_pass
logging:
level:
com.example: DEBUG
生产环境 application-prod.yml:
yaml
server:
port: 80
spring:
datasource:
url: jdbc:mysql://prod-server:3306/prod_db
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
logging:
level:
com.example: WARN
6.2 激活Profile的多种方式
| 方式 | 示例 | 优先级 |
|---|---|---|
| 配置文件 | spring.profiles.active=dev |
低 |
| 命令行参数 | --spring.profiles.active=prod |
最高 |
| JVM参数 | -Dspring.profiles.active=prod |
高 |
| 环境变量 | SPRING_PROFILES_ACTIVE=prod |
高 |
| 编程方式 | SpringApplication.setAdditionalProfiles("dev") |
- |
bash
# 命令行指定
java -jar app.jar --spring.profiles.active=prod
# JVM参数指定
java -Dspring.profiles.active=prod -jar app.jar
# 多Profile同时激活
java -jar app.jar --spring.profiles.active=prod,ssl
6.3 Profile分组(Spring Boot 2.4+)
yaml
spring:
profiles:
group:
production: prod,metrics,logging
staging: test,metrics
6.4 Profile条件装配
java
@Configuration
public class DataSourceConfig {
@Bean
@Profile("dev")
public DataSource devDataSource() {
// 内嵌H2数据库
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.build();
}
@Bean
@Profile("prod")
public DataSource prodDataSource() {
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl("jdbc:mysql://prod-server:3306/app");
return ds;
}
}
七、Starter机制
7.1 什么是Starter
Starter是Spring Boot提供的一组预定义依赖集合,引入一个Starter就能获得某个功能所需的全部依赖,且版本已经过官方兼容性测试。
7.2 常用Starter一览
| Starter | 用途 | 包含的主要依赖 |
|---|---|---|
spring-boot-starter-web |
Web开发 | Spring MVC + Tomcat + Jackson |
spring-boot-starter-data-jpa |
JPA数据访问 | Hibernate + Spring Data JPA |
spring-boot-starter-data-redis |
Redis | Spring Data Redis + Lettuce |
spring-boot-starter-security |
安全框架 | Spring Security |
spring-boot-starter-test |
测试 | JUnit 5 + Mockito + AssertJ |
spring-boot-starter-actuator |
监控 | Actuator端点 |
spring-boot-starter-mail |
邮件发送 | Spring Mail |
spring-boot-starter-thymeleaf |
模板引擎 | Thymeleaf |
spring-boot-starter-validation |
参数校验 | Hibernate Validator |
spring-boot-starter-aop |
AOP切面 | Spring AOP + AspectJ |
spring-boot-starter-cache |
缓存 | Spring Cache |
spring-boot-starter-amqp |
消息队列 | Spring AMQP (RabbitMQ) |
spring-boot-starter-kafka |
Kafka | Spring Kafka |
7.3 Starter的工作原理
以 spring-boot-starter-web 为例,引入依赖后:
spring-boot-starter-web
├── spring-boot-starter # 核心Starter
│ ├── spring-boot # Spring Boot核心
│ ├── spring-boot-autoconfigure # 自动配置
│ └── spring-core, spring-context, spring-beans...
├── spring-boot-starter-tomcat # 内嵌Tomcat
│ ├── tomcat-embed-core
│ ├── tomcat-embed-el
│ └── tomcat-embed-websocket
├── spring-webmvc # Spring MVC
├── jackson-databind # JSON处理
└── spring-boot-starter-logging # 日志(Logback)
不需要手动管理这些子依赖的版本号 ,spring-boot-starter-parent已经统一管理。
7.4 自定义Starter
创建一个自定义Starter需要两个模块:
1. 自动配置模块:my-spring-boot-autoconfigure
java
// 配置属性类
@Data
@ConfigurationProperties(prefix = "my.service")
public class MyServiceProperties {
private String endpoint = "http://localhost:8080";
private int timeout = 5000;
private boolean enabled = true;
}
// 业务服务
public class MyService {
private final MyServiceProperties properties;
public MyService(MyServiceProperties properties) {
this.properties = properties;
}
public String call() {
return "Calling " + properties.getEndpoint() + " with timeout " + properties.getTimeout();
}
}
// 自动配置类
@AutoConfiguration
@ConditionalOnClass(MyService.class)
@EnableConfigurationProperties(MyServiceProperties.class)
public class MyServiceAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "my.service", name = "enabled", havingValue = "true",
matchIfMissing = true)
public MyService myService(MyServiceProperties properties) {
return new MyService(properties);
}
}
2. 注册自动配置类(Spring Boot 3.x)
在 src/main/resources/META-INF/spring/ 目录下创建文件:
org.springframework.boot.autoconfigure.AutoConfiguration.imports:
com.example.autoconfigure.MyServiceAutoConfiguration
3. Starter模块:my-spring-boot-starter
xml
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>my-spring-boot-autoconfigure</artifactId>
<version>1.0.0</version>
</dependency>
<!-- 如果需要,还可以添加其他直接依赖 -->
</dependencies>
7.5 自定义Starter的最佳实践
| 规范 | 说明 |
|---|---|
| 命名 | 官方Starter:spring-boot-starter-xxx;第三方:xxx-spring-boot-starter |
| 配置类 | 使用@ConfigurationProperties而非@Value |
| 条件装配 | 充分利用@Conditional注解,提供覆盖能力 |
| 默认值 | 提供合理的默认值,做到零配置即可使用 |
| 文档 | 提供additional-spring-configuration-metadata.json支持IDE提示 |
八、Spring Boot生命周期与扩展点
8.1 启动流程
java
public static void main(String[] args) {
// 1. 创建SpringApplication实例
SpringApplication app = new SpringApplication(DemoApplication.class);
// 2. 设置自定义属性(可选)
app.setBannerMode(Banner.Mode.OFF);
app.setAdditionalProfiles("dev");
// 3. 运行应用
ConfigurableApplicationContext context = app.run(args);
}
8.2 常用扩展点
java
// 1. ApplicationRunner:应用启动后执行
@Component
public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
System.out.println("应用启动完成,执行初始化任务...");
System.out.println("非选项参数: " + args.getNonOptionArgs());
System.out.println("选项参数: " + args.getOptionNames());
}
}
// 2. CommandLineRunner:应用启动后执行(接收原始参数)
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) {
System.out.println("命令行参数: " + Arrays.toString(args));
}
}
// 3. 通过@Order控制执行顺序
@Component
@Order(1) // 数字越小越先执行
public class FirstRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
System.out.println("第一个执行");
}
}
// 4. EnvironmentPostProcessor:环境准备完成后、Bean创建前
public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
// 可以在此添加/修改配置源
}
}
// 5. BeanFactoryPostProcessor:Bean定义加载后、实例化前
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableBeanFactory beanFactory) {
System.out.println("Bean定义数量: " + beanFactory.getBeanDefinitionCount());
}
}
8.3 优雅关闭
yaml
# application.yml
server:
shutdown: graceful # Spring Boot 2.3+
spring:
lifecycle:
timeout-per-shutdown-phase: 30s # 等待时间
java
@Component
public class GracefulShutdownHandler implements DisposableBean {
@Override
public void destroy() {
System.out.println("应用即将关闭,执行清理工作...");
// 释放资源、关闭连接池等
}
}
九、常见面试题解析
Q1:Spring Boot自动配置的原理是什么?
答: Spring Boot通过@EnableAutoConfiguration注解开启自动配置。该注解导入了AutoConfigurationImportSelector,它会读取META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中的所有自动配置类。每个自动配置类都使用@Conditional系列注解进行条件判断,只有满足条件时才会生效。由于使用了@ConditionalOnMissingBean,用户自定义的Bean会优先覆盖自动配置的Bean。
Q2:@SpringBootApplication注解做了什么?
答: 它是三个注解的组合:
@SpringBootConfiguration:标记为配置类@EnableAutoConfiguration:开启自动配置@ComponentScan:扫描当前包及子包的组件
Q3:Spring Boot配置文件的加载优先级是怎样的?
答: 优先级从高到低:
- 命令行参数
--server.port=9090 file:./config/目录file:./根目录classpath:/config/类路径config包classpath:/类路径根目录
高优先级覆盖低优先级,相同优先级时.properties覆盖.yml。
Q4:Starter和普通依赖有什么区别?
答: Starter是一组相关依赖的集合,提供"开箱即用"的体验:
- 统一管理版本兼容性
- 引入一个Starter即可获得全部相关依赖
- 配合自动配置,无需手动配置Bean
- 普通依赖只是单一的库,需要自行管理版本和配置
Q5:如何自定义Starter?
答: 需要两个模块:
xxx-spring-boot-autoconfigure:包含配置属性类、核心业务类和@AutoConfiguration标注的自动配置类xxx-spring-boot-starter:只引入autoconfigure模块的依赖- 在
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports中注册配置类
十、总结与下篇预告
本文小结
| 知识点 | 核心要点 |
|---|---|
| Spring Boot定位 | Spring的脚手架,约定优于配置 |
| 核心注解 | @SpringBootApplication是三个注解的组合 |
| 自动配置 | @EnableAutoConfiguration → AutoConfigurationImportSelector → @Conditional过滤 |
| 配置文件 | .yml推荐,支持多Profile,@ConfigurationProperties批量绑定 |
| 多环境 | Profile文件 + spring.profiles.active激活 |
| Starter | 一站式依赖 + 自动配置 = 开箱即用 |
| 自定义Starter | @AutoConfiguration + @Conditional + @ConfigurationProperties |
下篇预告
🔜 第39篇:Spring Boot Web实战------我们将深入Web开发,学习RESTful API设计、参数校验、统一响应封装、全局异常处理、拦截器以及Swagger接口文档生成,从零搭建一个企业级Web项目骨架!
📚 参考资料
💬 互动问题
- 你在项目中使用的是
application.properties还是application.yml?为什么? - 你有没有遇到过自动配置冲突的问题?是怎么解决的?
- 如果让你设计一个自定义Starter,你会为什么功能设计?
欢迎在评论区分享你的经验和想法!🚀