SpringBoot使用一个全局配置文件,配置文件名固定:
- application.properties
- application.yml
application.properties端口设置8081,application.yml端口设置8082,运行启动类,优先走8081。
两个配置文件互补,application.properties优先级 > application.yml优先级。
目录
[1. 注入值](#1. 注入值)
[2. 松散绑定](#2. 松散绑定)
[3. SpEL](#3. SpEL)
[4. JSR303 数据校验](#4. JSR303 数据校验)
[5. 复杂类型封装](#5. 复杂类型封装)
@PropertySource&@ImportResource&@Bean
配置文件格式
YML配置格式:
-
k:(空格)v:表示一对键值对(空格必须有);
- 字符串默认不用加上单引号或者双引号;
- "":双引号;不会转义字符串里面的特殊字符;特殊字符会作为本身想表示的意思(例子:name: "zhangsan \n lisi":输出;zhangsan 换行 lisi)
- '':单引号;会转义特殊字符,特殊字符最终只是一个普通的字符串数据(例子:name: 'zhangsan \n lisi':输出;zhangsan \n lisi)
-
以空格的缩进来控制层级关系;只要是左对齐的一列数据,都是同一个层级的;
-
属性和值也是大小写敏感;
server:
port: 8085
properties配置格式:
server.port=8084
配置文件值注入
配置文件中,无论是yml还是properties他们都能获取到值。
在实体类上使用 @ConfigurationProperties 进行值注入。
- @ConfigurationProperties: 告诉SpringBoot将本类中的所有属性和配置文件中相关配置进行绑定,默认从全局配置文件中获取值。
- prefix = "person": 配置文件中哪个与本类中的属性进行一一映射
1. 注入值
前期准备:
-
创建实体类
-
person类:(简单属性)id、name、personname、address、boss、birth、
(复杂类型)lsit类型、map类型、dog对象、dog对象列表 -
dog类:id、name
javapublic class Person { private Integer id; private String name; private String address; private Boolean boss; private Date birth; private String personName; private List<String> hobby; private Map<String,Object> maps; private Dog dog; // 嵌套对象 private List<Dog> dogs; // dog对象列表 // 提供无参构造、有参构造、Getter和setter对象,以及重新toString } public class Dog { private String name; private Integer age; // 提供无参构造、有参构造、Getter和setter对象,以及重新toString } -
将实体类交由spring管理,在实体类上加上 @Component 注解
-
-
书写配置文件: 在application.yml配置文件中写person的属性值
-
简单属性
javaperson: # 普通属性 id: 1 name: "zhangsan \n lisi" address: 北京 boss: true birth: 2025/1/18 -
list集合
java# list集合书写 # 方式一 # lists: {篮球,足球} # 方式二 lists: - 篮球 - 足球 - 乒乓球 -
map集合
java# map集合书写 maps: {sex: male,email: 123456789@qq.com} -
dog属性
java# dog属性 dog: name: 小狗 age: 2 -
dog列表属性
java# dog对象list集合 # 方式一:行内列表格式 # dogs: # - name: 小黑 # age: 3 # - name: 小黄 # age: 2 # - {name: "金毛",age: 1} # 方式二:块式列表格式 dogs: - name: 小黑 age: 3 - name: 小黄 age: 2 - name: 金毛 age: 1 -
松散绑定
java# 松散绑定(下面的方式都可以实现) # personName: wangwu # person_name: wangwu # person-name: wangwu PERSONNAME: wangwu
-
-
绑定值
-
@Value: 需要对属性一个一个的进行注入,只能为简单属性进行注入,复杂类型不支持。 在使用@Value注解注入值时,并不强制要求属性提供setter方法。Spring框架可以通过反射直接设置字段的值,即使没有setter方法。
但是,如果类中的属性是私有的,并且没有setter方法,Spring会通过反射来设置值。然而,在实际开发中,为了符合JavaBean的规范,以及方便其他代码(如序列化、其他框架使用)使用,通常我们会提供getter和setter方法。
另外,需要注意的是,如果使用@Value注解在非Spring管理的类中,或者在没有Spring容器管理的环境下,那么注解将不会生效。因此,确保这个类是由Spring容器管理的(如使用@Component、@Service等注解,或者通过XML配置)。
由于复杂类型没有注入值,值为null。java//使用@Value注值 @Component //交给spring管理 public class Person { @Value("${person.id}") private Integer id; @Value("${person.name}") private String name; @Value("${person.address}") private String address; @Value("${person.boss}") private Boolean boss; @Value("${person.birth}") private Date birth; private String personName; private List<String> lists; private Map<String,Object> maps; private Dog dog; // 嵌套对象 private List<Dog> dogs; }
-
@ConfigurationProperties: 可以批量给属性注值,且复杂类型也可以进行注值 使用 @ConfigurationProperties 注解进行属性绑定时,必须提供 setter 方法,因为 Spring 是通过调用 setter 方法来注入属性的。同样,如果需要访问这些属性,也需要 getter 方法。
原因:
@ConfigurationProperties 绑定属性时,使用的是 JavaBean 的规范,即通过 setter 方法设置值。如果没有 setter 方法,Spring 将无法将属性值设置到对应的字段上。
但是,请注意:
-
如果使用 Lombok 的 @Data 注解,它会自动生成 getter 和 setter,这样就可以。
-
如果属性是 final 的,那么必须通过构造函数来注入,这时候就不能用 setter 了。
但是 @ConfigurationProperties 默认要求有无参构造函数和 setter,所以对于 final 字段,我们需要提供构造函数,并且使用 @ConstructorBinding 注解(在 Spring Boot 2.2 以后引入)。
java//方式二:使用注解 @Component //交给spring管理 @ConfigurationProperties(prefix = "person") public class Person { private Integer id; private String name; private String address; private Boolean boss; private Date birth; private String personName; private List<String> lists; private Map<String,Object> maps; private Dog dog; // 嵌套对象 private List<Dog> dogs; }
-
-
2. 松散绑定
就是 personName 字段在配置文件中以多种形式书写,都可以绑定值。
@ConfigurationProperties 支持,@Value 不支持
3. SpEL
@Value 配合 SpE不仅可以绑定简单属性,还能处理非常复杂的表达式和对象操作。
@ConfigurationProperties 不支持,@Value 支持
a. 配置文件内容
java
# SpEL 表达式
personDemo:
id: 1
name: "zhangsan"
address: 北京
boss: true
b. PersonDemo实体类
java
// 复杂 SpEL 表达式
@Component
public class PersonDemo {
@Value("${personDemo.name}")
private String name;
// 数学运算:计算结果为 15
@Value("#{10 + 5}")
private Integer rendomNumber;
// 将配置的值转为大写
@Value("#{'${personDemo.name}'.toUpperCase()}")
private String uppercaseName;
// 调用静态方法:生成 0-100 的随机数
@Value("#{T(java.lang.Math).random() * 100}")
private Double randomScore;
// 三元运算符:条件表达式
@Value("#{${personDemo.id} > 0 ? 'active' : 'inactive'}")
private String status;
@Value("#{${personDemo.boss} ? '领导' : '员工'}")
private String role;
// 正则表达式匹配
@Value("#{personDemo.name matches '[a-zA-Z]+'}")
private Boolean isNameValid;
// 列表操作
@Value("#{{'apple', 'banana', 'orange'}}")
private List<String> fruits;
}

4. JSR303 数据校验
@ConfigurationProperties 支持,@Value 不支持
a. 配置文件内容
java
# JSR303 数据校验
user-demo:
id: 2
name: lisi
email: 123456789@qq.com
phone: 13345678910
accepted: true
birth: 2026/2/20
b. User实体类
java
@Component
@ConfigurationProperties(prefix = "user-demo")
@Validated // 启用校验 JSR303 数据校验
public class UserDeno {
@NotNull(message = "ID不能为空")
@Min(value = 1, message = "ID必须大于0")
@Max(value = 10, message = "ID不能超过10")
private Integer id;
@NotBlank(message = "姓名不能为空")
@Size(min = 2, max = 10, message = "姓名长度必须在2-10之间")
private String name;
@Email(message = "邮箱格式不正确")
private String email;
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
private String phone;
@AssertTrue(message = "必须接收协议")
private Boolean accepted;
@Future(message = "生日必须是将来时间")
private Date birth;
}

5. 复杂类型封装
在person中的dog对象等属性的封装
@ConfigurationProperties 支持,@Value 不支持
@Value获取值和@ConfigurationProperties获取值比较

@PropertySource&@ImportResource&@Bean
@PropertySource
@PropertySource:加载指定的配置文件
- 新建一个 application-dev.properties 配置文件
java
user-demo.id=2
user-demo.name=李四
user-demo.email=3025147478@qq.com
user-demo.phone=15032722309
user-demo.accepted=true
user-demo.birth=2026/2/20
- 在UserDemo实体类上添加 @PropertySource 注解,指定配置文件
java
// @PropertySource指定加载配置文件
@PropertySource(value = {"classpath:application-dev.properties"})
@Component
@ConfigurationProperties(prefix = "user-demo")
@Validated // 启用校验 JSR303 数据校验
public class UserDemo {
@NotNull(message = "ID不能为空")
@Min(value = 1, message = "ID必须大于0")
@Max(value = 10, message = "ID不能超过10")
private Integer id;
@NotBlank(message = "姓名不能为空")
@Size(min = 2, max = 10, message = "姓名长度必须在2-10之间")
private String name;
@Email(message = "邮箱格式不正确")
private String email;
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
private String phone;
@AssertTrue(message = "必须接收协议")
private Boolean accepted;
@Future(message = "生日必须是将来时间")
private Date birth;
}

@ImportResource
@ImportResource:导入Spring的配置文件,让配置文件里面的内容生效;
Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;
想让Spring的配置文件生效,加载进来,在启动类上加**@ImportResource 注解**
- 在service包下创建 HelloService.java
java
public interface HelloService {
public void hello();
}
- 在service.impl下创建HelloServiceImpl.java
java
public class HelloServiceImpl implements HelloService {
@Override
public void hello() {
System.out.println("你好");
}
}
- 创建Spring配置文件:applicationContext.xml
XML
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="helloService" class="com.qcby.springBootDemoYml.service.impl.HelloServiceImpl"/>
</beans>
- 在启动类上添加**@ImportResource 注解**
java
@SpringBootApplication
// 导入spring的配置类让其生效
@ImportResource(locations = {"classpath:applicationContext.xml"})
public class SpringBootDemoYml {
public static void main(String[] args) {
SpringApplication.run(SpringBootDemoYml.class, args);
}
}
- 控制台输出:你好
@Bean
添加@Bean注解后,不在需要 applicationContext.xml 配置文件了,且不需要使用@ImportResource 注解。
- 创建WordService.java
java
public interface WordService {
public void helloWord();
}
- 创建WordServiceImpl.java
java
public class WordServiceImpl implements WordService {
@Override
public void helloWord() {
System.out.println("你好,世界!");
}
}
- 创建WordConfig.java
java
@Configuration // 声明当前是配置类
public class WordConfig {
@Bean // 只能声明在方法上
public WordService wordServiceBean(){
System.out.println("wordConfig配置类");
return new WordServiceImpl();
}
}
- 控制台输出:
wordConfig配置类 你好,世界!
配置文件占位符
占位符使用 ${} 形式。
随机数
java
${random.value}、${random.int}、${random.long}
${random.int(10)}、${random.int(0,100)}
-
创建Parent实体类,并绑定值
java@Component @ConfigurationProperties(prefix = "parent") public class Parent { private Integer id; private String name; private Integer age; private Date birth; private Boolean boss; private Map<String, Object> maps; private List<String> lists; private Dog dog; // 提供无参构造、有参构造、Getter和setter对象,以及重新toString } -
在application.yml配置文件中写属性值
java# 配置文件占位符 parent: id: ${random.int} name: "zhaoliu \n ${random.uuid}" age: 20 birth: 2028/12/12 boss: true maps: {email: 3025147478@qq.com, phone: 11111} lists: - 花花 - 草草 dog: name: ${parent.name:wangwu}小黄 # 若没有配置parent下的name属性值,默认使用wangwu;若配置类值,则使用配置的值 age: ${random.int(3,5)} # 生成0到5之间的随机整数
多Profile文件
外部指令优先级 > 配置文件
在配置文件中指定运行环境
有两种多配置文件形式:
-
properties:application-{profile}.properties

在主配置文件application.properties中指定运行环境java# 多配置文件 spring.profiles.active=dev -
yml:在application.yml中配置多个端口
java# 多配置文件 server: port: 8085 spring: profiles: active: dev --- server: port: 8084 spring: profiles: dev --- server: port: 8086 spring: profiles: prod # 指定属于那个环境
在外部指定运行环境
java
# java -jar 打包的项目名.jar --spring.profiles.active=环境名称
java -jar springbootdemoyml-1.0-SNAPSHOT.jar --spring.profiles.active=prod

配置文件加载位置
springboot启动会扫描一下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件;
SpringBoot会从这四个位置全部加载主配置文件;互补配置:
- --file:./config/
- --file:./
- --classpath:/config/
- --classpath:/

如果项目中存在这四个位置下的配置文件,加载顺序为:-file:./config/ > -file:./ > -classpath:/config/ > -classpath:/
外部配置加载顺序
命令行参数: 多个配置用空格分开; --配置项=值
-
在D:\code2024\application.properties,放在一个配置文件(端口号:8083),在外部命令行中运行这个环境
java# java -jar 打包的项目名.jar --spring.config.location=外部位置\application.properties java -jar springbootdemoyml-1.0-SNAPSHOT.jar --spring.config.location=D:\code2024\application.properties
-
在命令行中指定端口和路径
注意:在Spring Boot 2.x 之后,不在使用 --server.context-path 这个命令,而是使用 --server.servlet.context-path。java# java -jar 打包的项目名.jar --server.port=端口号 --server.servlet.context-path=路径 java -jar springbootdemoyml-1.0-SNAPSHOT.jar --server.port=8087 --server.servlet.context-path=/abc