热部署
热部署指在应用程序不停止运行的情况下,完成代码、配置或资源的更新并生效的技术。
spring为开发者提供了一个名为spring-boot-devtools的模块来使Spring Boot应用支持热部署,提高开发者的开发效率,无需手动重启Spring Boot应用。
java
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
修改代码后,通过ctrl+f9实现热部署,刷新页面可看到更新后的页面。
配置文件
Spring Boot 有两个固定名称的全局配置文件,用于修改框架自动配置的默认值:
application.properties:采用 "键 = 值" 的格式,例如server.port=8081表示将服务端口修改为 8081。application.yml(或application.yaml):采用 "层级缩进 + 键:值" 的格式,是 YAML 语言的文件形式,更易读且适合复杂配置。
yaml文件以数据为中心 ,通过缩进、冒号、短横线等简单语法组织层级数据。而xml等传统配置文件以<标签>嵌套的形式组织数据,冗余繁琐。
yaml语法
层级结构
通过缩进(空格,不能用制表符)表示层级关系,层级间用冒号+空格分隔。
java
# 示例:配置Spring Boot服务端口和数据库连接
server:
port: 8081 # 第一层:server,第二层:port
spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456
支持的数据类型
yaml支持常见的数据类型,SpringBoot会自动解析并映射到Java对象中:
- 字符串:默认无需引号,若包含特殊字符(如:空格)需用单引号'或双引号"包裹
- 数值:整数、浮点数直接写
- 布尔值:true/false小写
- 数组/列表:用- (短横线+空格)表示元素,支持多层嵌套
java
users:
- name: 张三
age: 20
- name: 李四
age: 22
# 简洁写法(一行表示)
tags: [java, spring, yaml]
- 对象、映射:键值对的层级结构,也可写成行内形式
java
# 行内对象写法
person: {name: 王五, age: 30}
特殊语法
- 注释:以#开头,仅单行注释
- 变量引用:用${}引用已定义的配置(或系统环境变量)
java
app:
name: MyApp
info:
app-name: ${app.name} # 引用上方的app.name
java-home: ${JAVA_HOME} # 引用系统环境变量
- 多文档拆分:在一个yaml文件中用---分隔多个配置文档
java
# 开发环境
spring:
profiles: dev
server:
port: 8080
---
# 生产环境
spring:
profiles: prod
server:
port: 80
配置文件值注入
配置文件:

javaBean:

如果导入配置文件处理器,以后编写配置就有提示了

properties配置文件在idea中默认utf-8可能会乱码

【说明】

@Value获取值和@ConfigurationProperties获取值比较

配置文件注入值数据校验

@PropertySource&@ImportResource&@Bean
@PropertySource:加载非全局配置文件
作用:
指定加载自定义的配置文件 (非application.yml/application.properties全局配置文件),让配置文件中的属性能被 Spring Boot 识别并绑定到 Java 类。
场景:
全局配置文件(application.yml)适合存放通用配置(如端口、环境),但如果有大量自定义配置(如person相关属性),可以单独放在person.properties中,用@PropertySource加载。
java
@PropertySource(value = {"classpath:person.properties"}) // 加载类路径下的person.properties
@Component // 必须是容器中的组件才能绑定配置
@ConfigurationProperties(prefix = "person") // 绑定配置文件中person前缀的属性
public class Person { ... }
@ConfigurationProperties默认只从全局配置文件加载属性,配合@PropertySource后,可扩展加载自定义配置文件。- 优先级:全局配置文件 >
@PropertySource指定的配置文件(若有同名属性,全局配置会覆盖)。
@ImportResource:导入传统 Spring 配置文件
作用:
让传统 Spring XML 配置文件 (如beans.xml)中的组件(<bean>标签定义的对象)生效,被 Spring Boot 容器识别。
背景:
Spring Boot 默认不识别传统的 Spring XML 配置文件(如<bean id="helloService" class="xxx.HelloService"/>),如果项目迁移时必须保留 XML 配置,就需要用@ImportResource手动导入。
使用方式:
标注在配置类上(通常是主启动类或专门的配置类):
java
@SpringBootApplication
@ImportResource(value = {"classpath:beans.xml"}) // 导入classpath下的beans.xml
public class MyApplication { ... }
@Bean:全注解方式注册组件(Spring Boot 推荐)
作用:
在配置类 中通过方法注册组件到 Spring 容器,替代传统 XML 配置中的<bean>标签,是 Spring Boot 推荐的组件注册方式。
为什么推荐?
传统 XML 配置(<bean>)繁琐且不直观,全注解方式(@Configuration + @Bean)更简洁,且便于代码维护。
java
// 配置类(替代XML配置文件)
@Configuration
public class MyConfig {
// 用@Bean注册一个HelloService对象到容器中
@Bean
public HelloService helloService() {
return new HelloService(); // 返回的对象会被Spring管理
}
}
// 其他类中可以直接注入使用
@Service
public class UserService {
@Autowired
HelloService helloService; // 这里能注入成功,因为helloService已经被@Bean注册到容器了
}
- 效果等同于 XML 中的:
<bean id="helloService02" class="xxx.HelloService"/>。 - 容器中可通过
@Autowired注入该组件:@Autowired HelloService helloService02;。
三者的核心区别与联系
| 注解 | 核心功能 | 适用场景 | 与 Spring Boot 的关系 |
|---|---|---|---|
@PropertySource |
加载自定义配置文件 | 拆分配置(全局配置 + 自定义配置) | 扩展配置文件来源 |
@ImportResource |
导入传统 Spring XML 配置文件 | 项目迁移时保留 XML 配置 | 兼容旧配置,非推荐方式 |
@Bean |
全注解方式注册组件 | 新项目中注册组件,替代 XML 的<bean>标签 |
推荐方式,符合 Spring Boot 设计理念 |
@PropertySource:管 "配置数据从哪个文件来",是数据来源的声明。@Bean:管 "哪个对象要被 Spring 管理",是对象创建的声明。
配置文件占位符
随机数占位符
Spring Boot 提供了${random}前缀的表达式,用于在配置文件中生成随机值,常见用法有:
${random.value}:生成随机字符串(无固定格式)。${random.int}:生成随机整数。${random.long}:生成随机长整数。${random.int(10)}:生成 0~10 之间的随机整数(左闭右开)。${random.int[1024,65536]}:生成 1024~65536 之间的随机整数(左闭右闭)。
属性引用与默认值占位符
格式为${已有属性名:默认值},作用是引用之前配置过的属性值 ,如果该属性不存在,则使用:后的默认值。
java
# 生成带随机UUID的姓名,如"张三a1b2c3-xxx-xxx"
person.last-name=张三${random.uuid}
# 生成随机年龄
person.age=${random.int}
# 引用不存在的属性"person.hello",则使用默认值"hello",最终dog.name为"hello_dog"
person.dog.name=${person.hello:hello}_dog
Profile多环境配置
Profile 用于区分 ** 开发(dev)、测试(test)、生产(prod)** 等不同环境的配置,实现 "一套代码,多环境适配"。
多 Profile 文件的两种实现方式
-
方式 1:多文件命名 主配置文件命名为
application-{profile}.properties/yml,例如:application-dev.yml(开发环境配置)application-prod.yml(生产环境配置)默认加载application.properties/yml(无环境标识的基础配置)。
-
方式 2:YAML 多文档块 在一个
application.yml中用---分隔多个环境配置,每个块用spring.profiles指定环境标识:
java
# 开发环境
spring:
profiles: dev
server:
port: 8080
---
# 生产环境
spring:
profiles: prod
server:
port: 80
激活指定 Profile 的三种方式
- 配置文件内指定 :在
application.yml或application.properties中添加spring.profiles.active=dev,直接指定激活的环境。 - 命令行指定:启动 Jar 包时通过参数指定,例如:
java
java -jar xxx.jar --spring.profiles.active=dev
- 虚拟机参数指定:启动时通过 JVM 参数指定,例如:
java
java -Dspring.profiles.active=dev -jar xxx.jar
配置文件加载位置
Spring Boot 启动时会扫描4 个默认位置 的application.properties/yml,优先级从高到低,高优先级配置会覆盖低优先级配置,且会 "互补配置"(即不同位置的配置会合并)。四个位置(优先级从高到低):
file:./config/(项目根目录下的config文件夹)file:./(项目根目录)classpath:/config/(类路径下的config文件夹,即src/main/resources/config)classpath:/(类路径根目录,即src/main/resources)
外部配置加载顺序
Spring Boot 支持从11 种来源 加载配置,优先级从高到低,高优先级配置覆盖低优先级配置,所有配置会 "互补配置"(即不同来源的配置会合并)。
| 优先级 | 配置来源 | 说明 |
|---|---|---|
| 1 | 命令行参数 | 启动时通过--配置项=值指定,例如--server.port=8081 |
| 2 | JNDI 属性(java:comp/env) | 用于 Java EE 容器的 JNDI 环境变量,一般少用 |
| 3 | Java 系统属性(System.getProperties ()) | JVM 的系统属性,例如-Dserver.port=8082 |
| 4 | 操作系统环境变量 | 系统级的环境变量,例如 Linux 的export SERVER_PORT=8083 |
| 5 | RandomValuePropertySource | 生成random.*开头的随机值(如${random.int}) |
| 6 | Jar 包外部的带 Profile 配置文件 | 如application-dev.yml(Jar 包外,且带环境标识) |
| 7 | Jar 包内部的带 Profile 配置文件 | 如application-dev.yml(Jar 包内,且带环境标识) |
| 8 | Jar 包外部的基础配置文件 | 如application.yml(Jar 包外,无环境标识) |
| 9 | Jar 包内部的基础配置文件 | 如application.yml(Jar 包内,无环境标识) |
| 10 | @PropertySource 注解 | 类上通过@PropertySource指定的自定义配置文件 |
| 11 | SpringApplication.setDefaultProperties | 代码中通过 API 设置的默认属性 |
自动配置原理
自动配置的执行流程
Spring Boot 的自动配置是通过@EnableAutoConfiguration注解触发的,核心步骤如下:
- 启动加载主配置类 :Spring Boot 启动时加载标注
@SpringBootApplication的主类,该注解包含@EnableAutoConfiguration,开启自动配置功能。 - 导入自动配置类 :
@EnableAutoConfiguration通过EnableAutoConfigurationImportSelector扫描所有 Jar 包中META-INF/spring.factories文件 ,读取其中org.springframework.boot.autoconfigure.EnableAutoConfiguration对应的配置类列表(如HttpEncodingAutoConfiguration、DataSourceAutoConfiguration等),并将这些类注入 Spring 容器。 - 自动配置类生效 :每个自动配置类(如
HttpEncodingAutoConfiguration)会根据自身的条件注解(如@ConditionalOnWebApplication)判断是否生效,生效后向容器中注入相关组件,并从对应的Properties类中读取配置(如HttpEncodingProperties读取spring.http.encoding前缀的配置)。
核心组件解析
-
spring.factories文件 :是自动配置的 "配置清单",位于 Jar 包的META-INF目录下,里面列出了所有需要自动加载的xxxAutoConfiguration类。例如,Spring Boot 内置的spring-boot-autoconfigure包中,spring.factories会配置数百个自动配置类,覆盖 Web、数据访问、消息队列等场景。 -
xxxAutoConfiguration类 :每个自动配置类都是一个 Spring 配置类(标注@Configuration),负责向容器中注入特定场景的组件。以HttpEncodingAutoConfiguration为例:- 它通过
@EnableConfigurationProperties(HttpEncodingProperties.class)绑定配置文件中spring.http.encoding前缀的属性。 - 通过
@ConditionalOnWebApplication(判断是否为 Web 环境)、@ConditionalOnClass(CharacterEncodingFilter.class)(判断类路径是否有字符编码过滤器)等条件注解,决定是否生效。 - 生效后,通过
@Bean注入CharacterEncodingFilter组件,实现 HTTP 编码的自动配置。
- 它通过
-
xxxProperties类 :是配置属性的 "载体",通过@ConfigurationProperties注解与配置文件中的属性绑定。例如HttpEncodingProperties会将spring.http.encoding.charset等配置映射到类的字段中,供自动配置类使用。
条件注解(@Conditional派生注解)
自动配置类是否生效,由一系列@Conditional派生注解决定,这些注解用于判断 "环境是否满足条件":
| 注解 | 作用 |
|---|---|
@ConditionalOnJava |
判断 JDK 版本是否符合要求 |
@ConditionalOnBean |
容器中存在指定 Bean 时生效 |
@ConditionalOnMissingBean |
容器中不存在指定 Bean 时生效 |
@ConditionalOnClass |
类路径中存在指定类时生效(如@ConditionalOnClass(CharacterEncodingFilter.class)) |
@ConditionalOnWebApplication |
当前是 Web 环境时生效 |
@ConditionalOnProperty |
配置文件中存在指定属性(或属性值匹配)时生效(如spring.http.encoding.enabled=true) |
调试与验证
可以通过在application.yml中添加debug: true,启动项目后查看控制台的自动配置报告:
Positive matches:表示生效的自动配置类。Negative matches:表示未生效的自动配置类(因条件不满足,如缺少依赖类、环境不匹配等)。