Spring Boot 快速开发
Java 中级 · Spring 生态
Spring Boot 的核心价值是约定优于配置 + 自动配置 + 起步依赖,让一个可运行的 Web 应用从「几十行 XML」变成「一个 @SpringBootApplication + 几行 yml」。但「自动」二字最容易让人稀里糊涂——本篇讲清自动配置到底是怎么生效的、条件注解怎么工作、配置加载顺序。
一、@SpringBootApplication 拆解
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}它其实是三个注解的组合:
| 注解 | 作用 |
|---|---|
@SpringBootConfiguration | 本质是 @Configuration,标记配置类 |
@ComponentScan | 扫描当前包及子包的组件 |
@EnableAutoConfiguration | 开启自动配置(核心) |
二、自动配置原理(重点)
2.1 条件注解:自动配置的「开关」
Spring Boot 不会无脑加载所有配置类,而是靠条件注解按需生效:
| 条件注解 | 生效条件 |
|---|---|
@ConditionalOnClass | 类路径存在某类(如引入了 DataSource 才配数据源) |
@ConditionalOnMissingBean | 容器里没有该 Bean 时才注册(给你留出覆盖空间) |
@ConditionalOnProperty | 配置项满足条件 |
@ConditionalOnWebApplication | 是 Web 应用 |
@ConditionalOnBean | 容器里有某 Bean |
@AutoConfiguration
@ConditionalOnClass(DataSource.class)
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfiguration {
@Bean
@ConditionalOnMissingBean // 你自己配了就不再用默认的
public DataSource dataSource(DataSourceProperties props) {
return props.initializeDataSourceBuilder().build();
}
}「我什么都没配,DataSource 哪来的?」
因为引入了 spring-boot-starter-jdbc/mybatis,类路径上有 DataSource,触发 DataSourceAutoConfiguration;又因为容器里没有 DataSource Bean,@ConditionalOnMissingBean 成立,于是自动创建。而你一旦自己 @Bean DataSource,自动配置就退让了——这就是「约定优于配置 + 可覆盖」。
2.2 调试自动配置
# application.yml:开启 debug,控制台会打印自动配置报告
debug: true报告分三部分:Positive matches(生效的)、Negative matches(因条件不满足跳过的)、Exclusions(排除的)。排查「为什么某个自动配置没生效」必看。
三、起步依赖(Starter)
Starter 是依赖的组合包,一个坐标引入一族依赖:
<!-- 一个 starter 自动带上 web/tomcat/jackson/validation 等 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 排除默认 tomcat,换成 undertow -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>常见 starter:web、data-jpa、data-redis、security、validation、actuator、test。
四、配置文件与加载优先级
Spring Boot 支持 application.properties / application.yml / application.yaml,以及 -{profile} 变体。
4.1 加载顺序(后者覆盖前者)
1. jar 包内 application.yml
2. jar 包内 application-{profile}.yml
3. jar 包外(同目录)application.yml
4. jar 包外 application-{profile}.yml
5. 命令行 --server.port=8081
6. 环境变量 / SPRING_APPLICATION_JSON
(越靠后优先级越高)4.2 多环境
# application.yml
spring:
profiles:
active: dev
---
# application-dev.yml
server:
port: 8080
---
# application-prod.yml
server:
port: 80# 启动指定环境
java -jar app.jar --spring.profiles.active=prod敏感配置别硬编码
密码、密钥等不要写死在 application.yml 提交到 Git。用环境变量、启动参数或配置中心(Nacos/Apollo)。@Value("${db.password}") 可从环境变量注入。
五、配置绑定:@ConfigurationProperties
比零散的 @Value 更好用,支持类型安全、层级、校验。
@ConfigurationProperties(prefix = "app.order")
@Validated
@Component
public class OrderProperties {
@NotNull
private Integer maxRetry;
private Duration timeout = Duration.ofSeconds(3);
private List<String> whiteList = new ArrayList<>();
// getter / setter
}app:
order:
max-retry: 3
timeout: 3s
white-list:
- 1001
- 1002| 对比 | @Value | @ConfigurationProperties |
|---|---|---|
| 批量绑定 | 逐条 | ✅ 整体 |
| 类型安全 | 弱 | ✅ 强 |
| 校验 / 松散绑定 | 否 | ✅(max-retry → maxRetry) |
六、Actuator:生产就绪
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
endpoint:
health:
show-details: always// 自定义健康检查
@Component
public class DbHealthIndicator implements HealthIndicator {
@Override
public Health health() {
return checkDb() ? Health.up().withDetail("db", "ok").build()
: Health.down().withDetail("db", "fail").build();
}
}常用端点:/actuator/health(健康)、/metrics(指标)、/prometheus(Prometheus 抓取)。
生产环境务必收敛端点
Actuator 的 /env、/beans、/heapdump 会泄露敏感信息。生产只暴露 health,其余加鉴权或关闭。
📚 官方文档与参考资料
✏️ 练习与自测
@SpringBootApplication由哪三个注解组成?自动配置的入口是哪个?@ConditionalOnClass和@ConditionalOnMissingBean的作用是什么?举一个「你配了它就不生效」的例子。- 开启
debug: true后,如何从自动配置报告判断某个配置为什么没生效? @Value和@ConfigurationProperties有什么区别?哪种更适合绑定额外配置对象?
本节小结
Spring Boot = @EnableAutoConfiguration + 条件注解筛选 + starter 组合依赖 + 外部化配置。自动配置的链路是:读 AutoConfiguration.imports → 拿候选配置类 → 条件注解筛选 → 注册 Bean;@ConditionalOnMissingBean 让你能覆盖默认配置。排查「为什么没生效」第一招就是 debug: true 看报告。