当前位置: 首页 > news >正文

SpringBoot中多配置文件和外部配置文件加载顺序

一、项目基础信息

1. 项目结构

基于 Maven 构建的 Spring Boot 项目,核心依赖包含 web、validation、devtools 等:

  • JDK 版本:17
  • Spring Boot 版本:3.2.0

2. 核心 POM 配置

xml

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.qcby</groupId> <artifactId>demo10</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.0</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- Web 核心依赖 --> <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> <!-- 热部署依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <!-- 参数校验依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> </dependencies> </project>

二、配置文件语法

Spring Boot 支持application.propertiesapplication.yml两种配置格式,优先读取 yml(层级更清晰)。

1. 基础配置示例(application.yml)

yaml

# 应用配置 app: name: demo-app port: 8081 allowed-ips: [127.0.0.1, 192.168.1.1] # 复杂对象配置 person: last-name: 张三${random.uuid} # 拼接随机UUID age: ${random.int} # 随机整数 birth: 2017/12/15 # 日期类型 boss: false # 布尔类型 maps: # Map类型 k1: v1 k2: 14 lists: [a, b, c] # List类型 dog: # 嵌套对象 name: ${person.hello:hello}_dog # 占位符+默认值 age: 15 # 用户配置(用于校验) user: id: 1 username: # 空值(用于校验演示) password: 123456 age: 25 email: lisi@example.com

2. properties 格式对比(application.properties)

properties

# 注意:properties 中特殊字符需转义,层级用 . 分隔 person.last-name=张三${random.uuid} person.age=${random.int} person.birth=2017/12/15 person.boss=false person.maps.k1=v1 person.maps.k2=14 person.lists=a,b,c person.dog.name=${person.hello:hello}_dog person.dog.age=15

3. 核心语法说明

  • 占位符${key}引用其他配置,${key:默认值}当 key 不存在时使用默认值;
  • 随机值${random.uuid}(随机 UUID)、${random.int}(随机整数);
  • 复杂类型:Map、List、嵌套对象均支持,yml 用缩进表示层级,properties 用.分隔层级。

三、配置绑定方式

1. @ConfigurationProperties(推荐,批量绑定)

核心规则
  • 注解加在类上,通过prefix指定配置前缀;
  • 类必须交给 Spring 容器管理(@Component);
  • 必须提供 getter/setter 方法(Spring 底层通过反射赋值);
  • 支持复杂类型(Map、List、嵌套对象)。
示例 1:Person 类绑定配置

java

运行

package com.qcby.model; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.Map; import java.util.List; import java.util.Date; @Component // 交给Spring容器管理 @ConfigurationProperties(prefix = "person") // 绑定person前缀的配置 public class Person { private String lastName; private Integer age; private Date birth; private Boolean boss; private Map<String, Object> maps; private List<Object> lists; private Dog dog; // 嵌套对象 // 嵌套静态内部类(也可单独定义) public static class Dog { private String name; private Integer age; // 必须提供getter/setter public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; } } // 所有属性的getter/setter public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } public Boolean getBoss() { return boss; } public void setBoss(Boolean boss) { this.boss = boss; } public Map<String, Object> getMaps() { return maps; } public void setMaps(Map<String, Object> maps) { this.maps = maps; } public List<Object> getLists() { return lists; } public void setLists(List<Object> lists) { this.lists = lists; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } @Override public String toString() { return "Person{" + "lastName='" + lastName + '\'' + ", age=" + age + ", birth=" + birth + ", boss=" + boss + ", maps=" + maps + ", lists=" + lists + ", dog=" + dog + '}'; } }
示例 2:@Value 单个绑定

@Value适合单个配置注入,不支持复杂类型(Map/List),语法更灵活(支持 SpEL)。

java

运行

package com.qcby.model; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class ValueDemo { // 注入单个配置值 @Value("${app.name}") private String appName; // 支持默认值:当app.port不存在时,使用8080 @Value("${app.port:8080}") private Integer appPort; // 支持SpEL表达式(Spring表达式语言) @Value("#{T(java.lang.Math).random() * 100}") private Double randomNum; @Override public String toString() { return "ValueDemo{" + "appName='" + appName + '\'' + ", appPort=" + appPort + ", randomNum=" + randomNum + '}'; } }

2. @ConfigurationProperties vs @Value 对比

特性@ConfigurationProperties@Value
批量绑定支持不支持
复杂类型(Map/List)支持不支持
SpEL 表达式不支持支持
默认值支持(配置文件中)支持(注解中)
校验注解支持(配合 @Validated)不支持

四、参数校验(JSR-380)

基于jakarta.validation注解,配合@Validated开启校验,需引入spring-boot-starter-validation依赖。

1. 核心注解说明

注解作用适用类型
@NotNull不能为 null所有类型
@NotBlank不能为 null / 空字符串 / 全空格字符串字符串
@Min(value)最小值数值类型(int/long)
@Max(value)最大值数值类型
@Email邮箱格式校验字符串

2. 校验示例(User 类)

java

运行

package com.qcby.model; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Min; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; @Component @ConfigurationProperties(prefix = "user") @Validated // 开启参数校验(核心) public class User { private Long id; @NotBlank(message = "用户名不能为空") // 字符串非空校验 private String username; @NotBlank(message = "密码不能为空") private String password; @NotNull(message = "年龄不能为空") // 不能为null @Min(value = 18, message = "年龄不能小于18岁") // 最小值校验 private Integer age; private String email; // getter/setter 必须提供 public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", age=" + age + ", email='" + email + '\'' + '}'; } }

3. 校验生效规则

  • 必须在类上添加@Validated注解;
  • 校验注解加在字段上,支持自定义提示语(message);
  • 若配置值不满足校验规则,项目启动时会抛出BindException异常。

五、配置绑定实战(Controller 调用)

通过@Autowired注入绑定配置的类,直接使用配置值。

java

运行

package com.qcby.controller; import com.qcby.model.Person; import com.qcby.model.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController // 等同于@Controller + @ResponseBody public class HelloController { @Autowired // 注入配置绑定的Person对象 private Person person; @Autowired // 注入配置绑定的User对象 private User user; @RequestMapping("/list") public void printConfig() { // 打印配置值 System.out.println(person); System.out.println(user); } }

六、Spring 容器配置补充

1. 配置类注册 Bean(@Configuration + @Bean)

java

运行

package com.qcby.config; import com.qcby.service.HelloService; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; // 标记为配置类(替代xml配置) @Configuration public class MyAppConfig { // 注册Bean到容器,默认名称为方法名(helloService) @Bean public HelloService helloService(){ System.out.println("配置类@Bean给容器中添加组件了..."); return new HelloService(); } }

2. 导入 XML 配置(@ImportResource)

若需兼容传统 XML 配置,在启动类添加注解:

java

运行

package com.qcby; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ImportResource; // 导入XML配置文件(beans.xml) @SpringBootApplication @ImportResource(locations = "classpath:beans.xml") public class Demo10Application { public static void main(String[] args) { SpringApplication.run(Demo10Application.class, args); } }

七、核心注意事项

  1. 配置绑定必须有 getter/setter:Spring 底层通过 set 方法赋值,无 set 方法则属性为 null;
  2. 配置前缀要匹配:@ConfigurationProperties(prefix = "person")需与配置文件中的 person 层级一致;
  3. 校验依赖必须引入:Spring Boot 3.x 后校验注解从javax.validation迁移到jakarta.validation,需引入spring-boot-starter-validation
  4. 热部署生效条件:devtools 依赖需加optional=true,IDEA 需开启自动编译(Settings -> Build -> Compiler -> Build project automatically);
  5. 配置文件优先级:application.yml > application.properties,同一配置在 yml 中定义会覆盖 properties。

总结

  1. Spring Boot 配置绑定优先使用@ConfigurationProperties(批量绑定、支持复杂类型),单个配置可使用@Value(支持 SpEL);
  2. 参数校验需引入 validation 依赖,配合@Validatedjakarta.validation注解使用;
  3. 配置文件中 yml 格式层级更清晰,优先级高于 properties,核心语法包含占位符、随机值、复杂类型定义。
http://www.jsqmd.com/news/299604/

相关文章:

  • Spring Boot 配置文件核心用法与加载优先级
  • Week 34: 量子深度学习入门:从 Neural ODE 到哈密顿量子演化
  • 什么是“同余数问题(千年数学难题)”?
  • Vue3+Node.js实现文件上传并发控制与安全防线 进阶篇
  • 大厂迷思:为什么顶级工程师会产出难以维护的代码
  • menset的使用方法
  • 数据结构学习笔记
  • “AUTOSAR?我连CAN都看不懂…” 一个汽车电子工程师的坦白与指南
  • SpringBoot整合Thymeleaf
  • 大数据领域数据中台的安全审计与合规
  • 数据结构01——时间复杂度和空间复杂度
  • Java中strip与trim()的区别
  • Python入门——字符串
  • 多级缓存必要性
  • OpenHarmony Flutter 分布式安全防护:跨设备身份认证与数据加密传输方案 - 指南
  • tp3.2性能暂时优化调整
  • 百万数据报表操作 - 努力-
  • 电商系统-下单功能 - 努力-
  • 软件测试—即时通讯测试方法
  • 告别if-else噩梦:流程编排技术
  • attn_scores注意力分计算-记录
  • 多头注意力中的张量重塑
  • 第二周作业wp
  • 吐血推荐专科生必用TOP9AI论文网站
  • Python 调用大模型(LLM) - 努力-
  • Python核心语法-Python自定义模块、Python包 - 努力-
  • 亲测好用9个一键生成论文工具,助本科生轻松写论文!
  • 为什么您的机房必须选择本地化 U 位资产管理系统?供应商服务深度解析
  • 人群仿真软件:Vadere_(3).用户界面操作
  • 人群仿真软件:Vadere_(1).Vadere简介与安装