一、配置文件的使用
SpringBoot使用一个全局的配置文件(核心配置文件),配置文件名在约定的情况下是固定的;配置文件的作用:修改SpringBoot自动配置的默认值;SpringBoot在底层都给我们自动配置好;
application.properties
application.yml

二、两种配置文件的格式
在springboot框架中,resource文件夹里可以存放配置的文件有两种:properties和yml。
1、application.properties的用法:扁平的k/v格式。(key/value)
server.port=8081
server.servlet.context-path=/tuling
2、application.yml的用法:树型结构 可读性更强 值前面一定要有空格
server:
port: 8088
servlet:
context-path: /tuling
三、配置文件的加载顺序
2.3.x:官方没有具体说明,实测以properties为准
2.4.0:如果指定了多个位置,则后一个位置可以覆盖前一个位置的值。
2.4.4:建议整个应用程序使用一种格式,如果您的配置文件的格式.properties和.yml都位于同一位置,则以properties优先级为准。
3.1.5:以.properties为准。
四、其它约定配置文件加载顺序
springboot启动还会扫描以下位置的application.properties或者application.yml文件作为Spring Boot的默认配置文件:
低:
1、classpath的根目录下的

2、classpath的根config/

3、项目根目录
如果当前项目是继承/耦合 关系maven项目的话,项目根目录=父maven项目的根目录

4、项目根目录/comfig

5、直接子目录/config


高

优先级由低到高,高优先级的配置会覆盖低优先级的配置;互补配置;
五、profile配置文件加载
Profile的意思是配置,对于应用程序来说,不同的环境要不同的配置。
SpringBoot框架提供了多profile的管理功能,我们可以使用profile功能来区分不同环境的配置。
1.Spring官方给出的语法规则是application-{properties}.properties(.yaml/.yml)。
2.如果需要创建自定义的properties文件时,可以用application-xxx-properties的命名方式。
六、配置文件值注入
1.@vaule
package com.example.hello.beans;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
//可以通过@Value + SPEL表达式来直接绑定springbooot配置文件中的值
@Component
public class User {
@Value("${user.username}")
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public List<String> getHobbies() {
return hobbies;
}
public void setHobbies(List<String> hobbies) {
this.hobbies = hobbies;
}
public Map<Integer, String> getGirlFriend() {
return girlFriend;
}
public void setGirlFriend(Map<Integer, String> girlFriend) {
this.girlFriend = girlFriend;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
private Integer age;
private Date birthday;
private List<String> hobbies;
private Map<Integer,String> girlFriend;
private Address address;
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", age=" + age +
", birthday=" + birthday +
", hobbies=" + hobbies +
", girlFriend=" + girlFriend +
", address=" + address +
'}';
}
}
package com.example.hello.beans;
import org.springframework.stereotype.Component;
@Component
public class Address {
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
private Integer id;
private String desc;
}
application.properties
user.username=123
server.port=8080
运行结果:

2.@ConfigurationProperties(prefix="user")
package com.example.hello.beans;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Component
@ConfigurationProperties(prefix ="user")
public class User {
// @Value("${user.username}")
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public List<String> getHobbies() {
return hobbies;
}
public void setHobbies(List<String> hobbies) {
this.hobbies = hobbies;
}
public Map<Integer, String> getGirlFriend() {
return girlFriend;
}
public void setGirlFriend(Map<Integer, String> girlFriend) {
this.girlFriend = girlFriend;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
// @Value("${user.age}")
private Integer age;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;
private List<String> hobbies;
private Map<Integer,String> girlFriend;
private Address address;
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", age=" + age +
", birthday=" + birthday +
", hobbies=" + hobbies +
", girlFriend=" + girlFriend +
", address=" + address +
'}';
}
}
user:
username: 徐庶
age: 25
birthday: 1999-01-01
hobbies:
- 读书
- 游泳
- 编程
girlFriend:
1: 貂蝉
2: 小乔
address:
id: 1
desc: 河南省郑州市
server:
port: 8080
运行结果:
User{username='徐庶', age=25, birthday=Fri Jan 01 00:00:00 CST 1999, hobbies=[读书, 游泳, 编程], girlFriend={1=貂蝉, 2=小乔}, address=Address{id=1, desc='河南省郑州市'}}

松散绑定:
user:
USERNAME: 徐庶
user:
userName: 徐庶
user:
user-name: 徐庶
user:
user_name: 徐庶
以上四种命名是可以自动绑定bean属性 User.username
3.@ConfigurationProperties对比@Value 获取值

JSR303数据校验,二者都支持

4.配置文件占位符
@ConfigurationProperties不支持SPEL表达式,只支持两种占位符。
1.对属性值的引用占位符

2.对属性随机值的引用


补:SPEL表达式
| 分类 | 核心内容 | 示例表达式 | 说明与用途 |
|---|---|---|---|
| 表达式的样子 | 写在 #{...} 里 |
#{3 + 5} |
这是 SpEL 的标准语法,一眼就能认出来,区别于属性占位符 ${...}(用于读取外部配置文件)。 |
| 支持的数据类型 | 字面量、数字、布尔、字符串、集合等 | #{'Hello'} #{1 > 0} #{1,2,3} |
支持常见的 Java 数据类型,还可以直接写集合,比如 List 和 Map。 |
| 能做什么运算 | 算术、比较、逻辑、三元、正则匹配 | #{1 + 2 * 3} #{score >= 60} #{age > 18 ? '成人' : '未成年'} |
几乎覆盖了所有常见的运算逻辑,可以替代很多简单的 Java 判断代码。 |
| 如何访问数据 | 操作对象属性、调用方法、访问容器 Bean | #{user.name} #{user.getName()} #{@userService.findById(1)} |
这是 SpEL 最核心的能力,可以灵活地读取或调用程序中的任何对象。用 @ 前缀就能直接拿到 Spring 容器里的 Bean。 |
| 特殊的变量 | 系统属性、方法参数、安全上下文等 | #{systemProperties['java.version']} #{#param1} #{authentication.name} |
内置了很多常用对象,让你能方便地获取环境信息或当前请求的上下文。参数用 #参数名 来引用。 |
| 处理空值 | 安全的导航操作符 | #{user?.address?.city ?: '未知'} |
?. 会优雅地处理空指针,如果中间任何一个对象是 null,就不会报错,直接返回 null 或指定的默认值。 |
| 主要应用场景 | 注解赋值、权限校验、条件化配置 | @Value("#{...}") @PreAuthorize("#{...}") @ConditionalOnExpression("...") |
这三个注解(见右侧)覆盖了 90% 以上的日常使用场景,让你的配置和代码变得非常灵活。 |
5.属性注入---数据校验

<!-- 数据校验-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'user' to com.example.hello.beans.User failed:
Property: user.address
Value: "null"
Reason: 不能为null
七、总结
自定义配置文件绑定值

