SpringBoot(01): 初识SpringBoot,从Spring的痛点说起
你有没有过这种体验?接手一个 SSM 项目,光是搞清楚配置文件就花了两三天。web.xml 配 Servlet,applicationContext.xml 配数据源,spring-mvc.xml 配视图解析,mybatis-config.xml 配 Mapper。等这些 XML 都搞定,才能开始写第一行业务代码。
SpringBoot 就是来解决这些问题的。这篇文章我们从 Spring 的痛点出发,手动搭建第一个 SpringBoot 项目,再深入理解自动配置原理和配置文件体系。
一、SpringBoot 到底解决了什么问题?
1.1 先说说 Spring 生态
很多人分不清 Spring、SpringMVC、SpringBoot 的关系,先理清楚:

- Spring Framework 是底层基础设施,提供 IoC 容器(控制反转)、DI(依赖注入)、AOP(面向切面编程)这些核心能力
- SpringBoot 是建立在 Spring Framework 之上的快速开发框架,帮你自动配置、内嵌服务器、管理依赖版本
- Spring Cloud 基于 SpringBoot,提供微服务架构的各种组件(注册中心、配置中心、网关等)
打个比方:Spring Framework 是毛坯房,啥都有但啥都得自己装;SpringBoot 是精装房,拎包入住;Spring Cloud 是小区,提供物业、安保、停车等配套服务。
1.2 传统 SSM 开发有多痛?
用 SSM(Spring + SpringMVC + MyBatis)框架开发一个 Web 项目,大概要走这么个流程:

左边的步骤,一个都不能少。而且每一步都可能出问题:
配置地狱:光 XML 配置文件就要写四五个,Servlet 3.0 之前连 web.xml 都不能省。数据源、事务管理器、视图解析器、MyBatis SqlSessionFactory,全都得手动配。
版本冲突 :Spring 5.x 要配 MyBatis 3.5.x,MyBatis 要配 mybatis-spring 2.x,数据库驱动、连接池、日志框架......一个版本对不上,运行时就给你报 ClassNotFoundException 或 NoSuchMethodError。排查起来费时费力。
部署繁琐:项目要打成 WAR 包,丢到外部 Tomcat 的 webapps 目录下。Tomcat 版本、JDK 版本、操作系统环境,每个环节都可能出幺蛾子。开发环境和生产环境不一致的问题,困扰了不少人。
启动慢:Tomcat 启动要加载所有组件,项目稍微大点,启动就得二三十秒。开发调试的时候反复重启,体验很差。
1.3 SpringBoot 怎么解决的?
SpringBoot 对上面这些痛点,逐一给出了方案:
| 痛点 | SSM 方案 | SpringBoot 方案 |
|---|---|---|
| 配置繁琐 | 手写多个 XML | 自动配置,零 XML |
| 依赖管理 | 手动管理版本,容易冲突 | Starter 自动管理版本 |
| 部署方式 | WAR 包 + 外部 Tomcat | JAR 包 + 内嵌服务器 |
| 项目搭建 | 手动创建项目结构 | Spring Initializr 一键生成 |
| 监控能力 | 需要自己集成 | Actuator 开箱即用 |
SpringBoot 的设计理念就四个字:约定优于配置 。它预先定好了一套约定,你照着来就行,大部分东西不用配。比如你引入了 spring-boot-starter-web,它就自动帮你配好内嵌 Tomcat、DispatcherServlet、JSON 序列化。
想自定义?没问题。SpringBoot 只是给个合理的默认值,你随时可以通过配置文件覆盖。
1.4 SpringBoot 的核心特性
总结下来,SpringBoot 有这几个核心特性:
自动配置(Auto-Configuration) :根据 classpath 中的类和已有的 Bean,自动配置 Spring 应用。你引入什么依赖,它就自动配什么。
起步依赖(Starter) :把一组相关的依赖打包成一个 Starter POM。比如 spring-boot-starter-web 一个依赖就包含了 Spring MVC、Tomcat、Jackson 这些。
内嵌服务器 :不需要外部部署 Servlet 容器,应用自带 Tomcat(也支持 Jetty、Undertow),java -jar 直接运行。
Actuator:提供健康检查、指标监控、配置查看等生产级功能,运维特别好用。
二、5 分钟搭建你的第一个 SpringBoot 项目
2.1 环境准备
搭建之前,确保你本地有这些环境:
- JDK 8+(推荐 JDK 8 或 JDK 11,生产环境用得最多)
- Maven 3.6+(或者 Gradle,本文用 Maven)
- 一个顺手的 IDE(IDEA 为佳)
验证一下环境:
shell
java -version
# java version "1.8.0_371"
mvn -version
# Apache Maven 3.9.3
2.2 用 Spring Initializr 生成项目
最简单的方式是用 Spring Initializr,这是官方提供的项目生成工具。
打开页面后,做如下选择:
- Project:Maven
- Language:Java
- Spring Boot:2.7.x(如果你用 JDK 8,选 2.7.x;JDK 17+ 可以选 3.x)
- Group:com.example
- Artifact:demo
- Packaging:Jar
- Java:8
然后点 "Add Dependencies",搜索并勾选 Spring Web。
点 "Generate" 下载 zip 包,解压后用 IDEA 打开即可。
2.3 手动创建项目
如果你不想用网页工具,手动创建也很快。先看项目结构:
css
springboot-demo/
├── pom.xml
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── demo/
│ │ │ └── DemoApplication.java
│ │ └── resources/
│ │ ├── application.yml
│ │ ├── static/
│ │ └── templates/
│ └── test/
│ └── java/
│ └── com/
│ └── example/
│ └── demo/
│ └── DemoApplicationTests.java
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>2.7.18</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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>
注意几个关键点:
spring-boot-starter-parent做了依赖版本管理,你不用指定 Spring、Jackson、Tomcat 这些依赖的版本号spring-boot-starter-web一个依赖就引入了 Spring MVC + 内嵌 Tomcat + JSON 支持spring-boot-maven-plugin打包用的,把项目打成可执行的 fat jar
启动类:
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);
}
}
@SpringBootApplication 是个组合注解,后面讲原理的时候会拆开分析。现在你只需要知道,加上这个注解,SpringBoot 就会自动帮你做三件事:标记配置类、开启自动配置、扫描组件。
2.4 写第一个接口
创建一个 Controller:
java
package com.example.demo.controller;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
public class HelloController {
@GetMapping("/hello")
public String hello(@RequestParam(defaultValue = "World") String name) {
return "Hello, " + name + "!";
}
@PostMapping("/user")
public User createUser(@RequestBody User user) {
user.setId(System.currentTimeMillis());
return user;
}
public static class User {
private Long id;
private String name;
private String email;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
}
}
在 IDEA 中运行 DemoApplication.main(),控制台会看到 Spring Boot 的 banner 和启动日志。默认端口是 8080。
测试一下:
java
curl http://localhost:8080/api/hello
# "Hello, World!"
curl http://localhost:8080/api/hello?name=SpringBoot
# "Hello, SpringBoot!"
curl -X POST http://localhost:8080/api/user \
-H "Content-Type: application/json" \
-d '{"name":"张三","email":"zhangsan@example.com"}'
# {"id":1748325678901,"name":"张三","email":"zhangsan@example.com"}
就这么简单,不需要任何 XML 配置,不需要部署 Tomcat,一个 main() 方法就把 Web 服务跑起来了。
2.5 SpringBoot 项目结构解析
SpringBoot 的项目结构有明确的约定:
| 目录 | 用途 |
|---|---|
src/main/java/ |
Java 源代码,启动类放在根包下 |
src/main/resources/ |
资源文件 |
src/main/resources/application.yml |
配置文件 |
src/main/resources/static/ |
静态资源(HTML、CSS、JS) |
src/main/resources/templates/ |
模板文件(Thymeleaf 等) |
src/test/java/ |
测试代码 |
启动类放在根包下是有讲究的。@SpringBootApplication 注解默认扫描当前类所在包及其子包下的所有组件。如果你把启动类放在 com.example 下,那 com.example.controller、com.example.service、com.example.dao 这些包里的 @Component、@Service、@Repository 都会被自动扫描到。
如果你非要换启动类的位置,可以手动指定扫描范围:
java
@SpringBootApplication(scanBasePackages = "com.example")
但除非有特殊需求,别这么干,按约定来就好。
2.6 常用 Starter 一览
SpringBoot 提供了一大堆官方 Starter,覆盖了大部分开发场景:
| Starter | 功能 |
|---|---|
spring-boot-starter-web |
Web 开发(Spring MVC + Tomcat) |
spring-boot-starter-data-jpa |
JPA 数据库操作 |
spring-boot-starter-data-redis |
Redis 缓存 |
spring-boot-starter-security |
安全认证 |
spring-boot-starter-amqp |
RabbitMQ 消息队列 |
spring-boot-starter-actuator |
应用监控 |
spring-boot-starter-test |
测试框架 |
spring-boot-starter-validation |
参数校验 |
spring-boot-starter-mail |
邮件发送 |
spring-boot-starter-aop |
AOP 切面编程 |
命名规则也简单:官方的叫 spring-boot-starter-*,第三方的叫 *-spring-boot-starter。比如 MyBatis-Plus 提供的 Starter 叫 mybatis-plus-boot-starter。
三、一文搞懂 SpringBoot 自动配置原理
自动配置是 SpringBoot 最核心的特性,也是面试高频考点。
3.1 @SpringBootApplication 注解拆解
一切从 @SpringBootApplication 开始。看源码(SpringBoot 2.7.x):
java
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class)
})
public @interface SpringBootApplication {
// ...
}

它是由三个注解组合而成的:
@SpringBootConfiguration :本质上就是 @Configuration,表示当前类是一个配置类,可以声明 @Bean 方法。SpringBoot 把它单独拿出来,语义上更清晰。
@EnableAutoConfiguration :这是自动配置的入口注解,核心中的核心。它通过 @Import(AutoConfigurationImportSelector.class) 导入了一个选择器,这个选择器负责加载所有自动配置类。
@ComponentScan :开启组件扫描。默认扫描当前类所在包及其子包,把 @Controller、@Service、@Repository 这些注解标记的类注册为 Bean。excludeFilters 排除了一些不需要的类,避免自动配置类被重复扫描。
3.2 自动配置的完整流程
整个自动配置的过程,可以分成这几步:

详细说一下:
第一步:启动入口
java
SpringApplication.run(DemoApplication.class, args);
这行代码做了两件事:创建 SpringApplication 实例,然后调用 run() 方法。
第二步:创建 SpringApplication 实例
java
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
// 推断应用类型:Servlet、Reactive 还是 None
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 加载 ApplicationContextInitializer
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 加载 ApplicationListener
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// 推断主配置类
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
}
这里已经在用 SpringFactoriesLoader 了------跟后面自动配置用的是同一个机制。
第三步:@EnableAutoConfiguration 触发自动配置
java
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
AutoConfigurationImportSelector 是自动配置的核心类。它的 selectImports() 方法会从 spring.factories 文件中读取所有自动配置类的全限定名。
第四步:读取 spring.factories
SpringFactoriesLoader 会扫描 classpath 下所有 jar 包的 META-INF/spring.factories 文件:
java
# spring-boot-autoconfigure-2.7.18.jar
# /META-INF/spring.factories(部分内容)
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
...
这个文件列出了 130+ 个自动配置类(不同版本数量不同)。但并不意味着所有配置类都会生效。
第五步:条件注解过滤
这是关键一步。每个自动配置类上都有一堆条件注解,只有满足条件的才会被注册到容器中。
拿 DataSourceAutoConfiguration 举例:
java
@AutoConfiguration
@ConditionalOnClass(DataSource.class)
@ConditionalOnMissingBean(DataSource.class)
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({DataSourcePoolMetadataProvidersConfiguration.class,
DataSourceInitializationConfiguration.class})
public class DataSourceAutoConfiguration {
// ...
}
它的条件是:
@ConditionalOnClass(DataSource.class):classpath 中必须有DataSource类,也就是你引入了 JDBC 相关的依赖@ConditionalOnMissingBean(DataSource.class):容器中还没有DataSourceBean,如果你自己定义了,这个自动配置就跳过
如果你没引入 JDBC 依赖,DataSource 类不在 classpath 中,这个配置类直接被跳过。这就是 SpringBoot 的"智能"之处------你引入什么依赖,它就配什么;没引入的,它不会瞎配。
3.3 条件注解详解
SpringBoot 提供了一套丰富的条件注解,都在 org.springframework.boot.autoconfigure.condition 包下:
| 注解 | 生效条件 |
|---|---|
@ConditionalOnClass |
classpath 中存在指定的类 |
@ConditionalOnMissingClass |
classpath 中不存在指定的类 |
@ConditionalOnBean |
容器中已存在指定的 Bean |
@ConditionalOnMissingBean |
容器中不存在指定的 Bean |
@ConditionalOnProperty |
配置文件中指定的属性满足条件 |
@ConditionalOnWebApplication |
当前是 Web 应用 |
@ConditionalOnNotWebApplication |
当前不是 Web 应用 |
@ConditionalOnExpression |
SpEL 表达式为 true |
@ConditionalOnSingleCandidate |
容器中指定类型的 Bean 只有一个 |
@ConditionalOnResource |
classpath 中存在指定的资源文件 |
其中用得最多的是 @ConditionalOnClass、@ConditionalOnMissingBean 和 @ConditionalOnProperty。
@ConditionalOnMissingBean 的设计思路值得说一说。它允许开发者用自己的 Bean 覆盖 SpringBoot 的默认配置。比如你手动定义了一个 DataSource Bean,SpringBoot 就不会再自动创建。默认给你配好,你要自定义也行。
3.4 自动配置的"开"和"关"
有时候你可能不想让某个自动配置生效。SpringBoot 提供了几种排除方式:
方式一:@SpringBootApplication 的 exclude 属性
java
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class DemoApplication {
// ...
}
方式二:@EnableAutoConfiguration 的 exclude 属性
java
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
方式三:配置文件
java
spring:
autoconfigure:
exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
方式四:调试模式
如果你想知道到底哪些自动配置类生效了、哪些没生效,可以开启调试模式:
java
debug: true
或者启动时加参数:
java
java -jar demo.jar --debug
启动日志里会打印一份报告:
java
============================
CONDITIONS EVALUATION REPORT
============================
Positive matches:(生效的自动配置)
-----------------
DataSourceAutoConfiguration matched:
- @ConditionalOnClass found required classes 'javax.sql.DataSource', 'org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType' (OnClassCondition)
Negative matches:(未生效的自动配置)
-----------------
RedisAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.springframework.data.redis.core.RedisOperations' (OnClassCondition)
这个报告排查问题的时候非常有用。
3.5 以 WebMvcAutoConfiguration 为例走一遍
我们拿 WebMvcAutoConfiguration 来实际走一遍自动配置的过程,看看 SpringBoot 到底帮我们配了什么。
java
@AutoConfiguration(after = ServletWebServerFactoryAutoConfiguration.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
public class WebMvcAutoConfiguration {
// ...
}
条件分析:
- 必须是 Servlet 类型的 Web 应用
- classpath 中必须有 Servlet API、Spring MVC 的核心类
- 容器中没有自定义的
WebMvcConfigurationSupport(如果你继承了WebMvcConfigurationSupport,这个自动配置就失效了)
当这些条件都满足时,WebMvcAutoConfiguration 会帮你配置:
DispatcherServlet(前端控制器)HttpMessageConverter(JSON/XML 序列化)- 静态资源处理(
/static、/public、/resources、/META-INF/resources) - 错误页面(默认的白板错误页)
- 日期格式化等
这就是为什么你加了 spring-boot-starter-web 依赖,不用写 web.xml,DispatcherServlet 就配好了。
四、application.yml 配置文件完全指南
4.1 两种配置文件格式
SpringBoot 支持两种配置文件格式:properties 和 yml。
application.properties:
ini
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/demo
spring.datasource.username=root
spring.datasource.password=123456
application.yml:
yaml
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/demo
username: root
password: 123456
两种格式功能完全等价,但 yml 的层级结构更清晰,可读性更好。实际项目中用 yml 的居多。
两个文件可以共存,同一属性以 properties 为准。但一般只保留一个,避免混乱。
4.2 YAML 语法基础
YAML 是一种缩进式的数据格式,有几个规则需要知道:
yaml
# 基本键值对
server:
port: 8080 # 数字,不需要引号
address: 0.0.0.0 # 字符串
# 列表
spring:
mvc:
view:
suffixes: .html,.jsp # 逗号分隔的列表
# 多行列表
server:
tomcat:
additional-tld-patterns:
- *.tld
- *.jar
# 布尔值
spring:
main:
lazy-initialization: false # true 或 false
# 占位符
app:
name: my-app
description: ${app.name} is a demo project
# 多行文本
app:
banner: |
========
My App
========
注意几个坑:
- yml 里缩进用空格,不能用 Tab
- 冒号后面必须有一个空格
- 字符串一般不需要引号,但包含特殊字符时要加引号
4.3 配置文件的加载优先级
SpringBoot 的配置来源非常多,不同来源有优先级之分。高优先级的配置会覆盖低优先级的:

最常用的几个:
命令行参数 :优先级最高。启动时通过 -- 传入:
css
java -jar demo.jar --server.port=8081 --spring.profiles.active=prod
这在你需要临时改配置的时候特别有用,不用重新打包。
环境变量 :操作系统级别的环境变量也能被 SpringBoot 读取。比如 SERVER_PORT=8081 对应 server.port=8081。Docker/K8s 部署时常用这种方式注入配置。
jar 包外部的配置文件 :SpringBoot 会自动读取 jar 包同级目录和 config/ 子目录下的配置文件。这意味着你不用改 jar 包,只需要在旁边放一个 application.yml 就能覆盖默认配置。
arduino
myapp/
├── config/
│ └── application.yml ← 优先级高(外部 config 目录)
├── application.yml ← 优先级中(外部同级目录)
└── demo.jar ← jar 包内配置优先级最低
jar 包内部的配置文件 :就是打包进 jar 的 application.yml,优先级最低。
记住一个原则:外部配置覆盖内部配置,命令行参数覆盖一切。
4.4 Profile 多环境配置
实际开发中,开发环境、测试环境、生产环境的配置肯定不同。SpringBoot 通过 Profile 机制来解决这个问题。
创建三个配置文件:
application.yml ← 公共配置
application-dev.yml ← 开发环境
application-test.yml ← 测试环境
application-prod.yml ← 生产环境
公共配置 application.yml:
yaml
spring:
profiles:
active: dev # 默认激活 dev 环境
app:
name: springboot-demo
开发环境 application-dev.yml:
yaml
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/dev_db
username: root
password: root
logging:
level:
root: DEBUG
生产环境 application-prod.yml:
yaml
server:
port: 80
spring:
datasource:
url: jdbc:mysql://10.0.1.100:3306/prod_db
username: prod_user
password: ${DB_PASSWORD} # 从环境变量读取
logging:
level:
root: WARN
注意生产环境用了 ${DB_PASSWORD} 占位符,从环境变量读取密码,避免敏感信息写在配置文件里。
激活 Profile 的方式:
ini
# 方式一:命令行参数
java -jar demo.jar --spring.profiles.active=prod
# 方式二:环境变量
export SPRING_PROFILES_ACTIVE=prod
java -jar demo.jar
# 方式三:JVM 参数
java -Dspring.profiles.active=prod -jar demo.jar
# 方式四:配置文件中指定(见上面的公共配置)
优先级也是命令行 > 环境变量 > JVM 参数 > 配置文件。
4.5 读取配置的方式
SpringBoot 提供了好几种读取配置值的方式:
方式一:@Value 注解
typescript
@RestController
public class ConfigController {
@Value("${server.port}")
private int serverPort;
@Value("${app.name:default-app}")
private String appName;
@GetMapping("/config")
public Map<String, Object> getConfig() {
Map<String, Object> map = new HashMap<>();
map.put("serverPort", serverPort);
map.put("appName", appName);
return map;
}
}
@Value 适合读取少量配置。${app.name:default-app} 中冒号后面是默认值,配置文件里没写的话就用这个默认值。
方式二:@ConfigurationProperties(推荐)
当配置项比较多的时候,用 @ConfigurationProperties 更优雅:
typescript
@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private String name;
private String description;
private int maxRetry = 3; // 默认值
private List<String> servers = new ArrayList<>();
// getter 和 setter 必须有
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
public int getMaxRetry() { return maxRetry; }
public void setMaxRetry(int maxRetry) { this.maxRetry = maxRetry; }
public List<String> getServers() { return servers; }
public void setServers(List<String> servers) { this.servers = servers; }
}
对应的配置文件:
yaml
app:
name: my-app
description: SpringBoot 配置演示项目
max-retry: 5
servers:
- 10.0.0.1:8080
- 10.0.0.2:8080
- 10.0.0.3:8080
@ConfigurationProperties 的优势:
- 类型安全,自动转换(String → int、String → List 等)
- 支持松散绑定(配置文件写
max-retry,Java 里写maxRetry,能自动对应) - 支持 JSR-303 校验(加
@Validated注解) - 批量绑定,不用一个一个写
@Value
方式三:Environment 对象
typescript
@Autowired
private Environment env;
@GetMapping("/env")
public String getEnv() {
return env.getProperty("app.name", "unknown");
}
Environment 是 Spring 的核心接口,能访问所有配置来源(配置文件、环境变量、JVM 参数等)。适合需要动态获取配置的场景。
4.6 配置值的特殊用法
随机值:测试的时候经常需要随机端口、随机字符串,SpringBoot 内置了随机值生成:
yaml
app:
secret: ${random.value} # 随机字符串
number: ${random.int} # 随机整数
big-number: ${random.long} # 随机长整数
uuid: ${random.uuid} # 随机 UUID
port: ${random.int[10000,19999]} # 范围内的随机整数
多配置文件引用:
yaml
# application.yml
spring:
profiles:
include:
- database # 额外加载 application-database.yml
- redis # 额外加载 application-redis.yml
include 和 active 的区别:active 会替换掉当前的 Profile,include 是在当前 Profile 的基础上额外加载。
配置文件中的占位符:
bash
app:
base-url: http://localhost:8080
api-url: ${app.base-url}/api/v1
ws-url: ${app.base-url:ws://localhost:8080}/ws
第三个配置中 ${app.base-url:ws://localhost:8080} 的意思是:如果 app.base-url 有值就用它,没有就用冒号后面的默认值。
总结
这篇文章覆盖了 SpringBoot 的四个基础知识点:
- SpringBoot 解决的核心问题是配置繁琐 和部署复杂,通过自动配置、起步依赖、内嵌服务器三板斧来简化开发
- 搭建 SpringBoot 项目用 Spring Initializr 或者手动创建都很快,关键是理解项目结构约定和 Starter 机制
- 自动配置的原理是
@EnableAutoConfiguration→SpringFactoriesLoader→spring.factories→ 条件注解过滤,最终只有满足条件的配置类才会注册 Bean - 配置文件支持 properties 和 yml 两种格式,通过 Profile 实现多环境管理,配置优先级遵循"外部覆盖内部"的原则