SpringBoot 配置文件
代码示例:SpringBoot-Labs-Junw jLab-1
1. 概述
Spring Boot 支持 Properties、YAML、JSON 三种格式的配置文件。目前主流的采用的是 Properties 或是 YAML 格式。本文的示例,我们会以 application.yml
配置文件为主。
主要内容如下:
自定义配置:读取配置文件中的自定义属性
@ConfigurationProperties
@Value
配置引用:配置项可以引用其他的配置项
命令行配置:用命令行中的配置覆盖掉配置文件中对应属性的值
多环境配置:多套配置 local、dev、pre、prod 可切换
自定义配置文件:读取多个配置文件
@PropertySources
配置加载顺序:加载优先级
代码样例:SpringBoot-Labs-Junw - jLab-1
省略了较少使用的配置项随机数、配置加密,后续如果用到的话再进行补充。
2. 自定义配置
在
application.yml
配置文件中自定义配置使用
@ConfigurationProperties
和@Value
注解,读取该自定义配置项目代码使用 Spring io 脚手架初始化生成,所以会与下文略有不同。
2.1 pom 中引入依赖
<?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>3.3.0</version>
<relativePath/>
</parent>
<artifactId>jLab-1-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- Spring Boot Starter 基础依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Spring Boot 配置处理器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
2.1.1 spring-boot-configuration-processor
编译项目时,会扫描 @ConfigurationProperties
注解,生成 spring-configuration-metadata.json
配置元数据文件给 IDEA。这样在 IDEA 中,可以带来两个好处:
在
application.yml
配置文件,添加配置项时,IDEA 会给出提示。点击配置项时,可以跳转到对应的
@ConfigurationProperties
注解的配置类。
注:.yml
可以, .yaml
不可以
2.2 配置文件
在 application.yml
中,添加自定义配置
注:单词之间,Spring Boot 推荐使用 -
中划线间隔。
work:
good-job-times: 100 # 特别优秀的完成工作的次数,单位:次。
completed-job-times: 100 # 完成工作的次数,单位:次
2.3 配置类
创建 WorkProperties 配置类,读取 work
配置项:
在类上,添加
@Component
注解,保证该配置类可以作为一个 Bean 被扫描到。在类上,添加
@ConfigurationProperties
注解,并设置prefix = "work"
属性,这样它就可以读取前缀为work
配置项,设置到配置类对应的属性上。
@Component
@ConfigurationProperties(prefix = "work")
public class WorkProperties {
/**
* 特别优秀的完成工作的次数,单位:次。
*/
private Integer goodJobTimes;
/**
* 完成工作的次数,单位:次。
*/
private Integer completedJobTimes;
// ... 省略 set/get 方法
// 快捷键 Alt + Ins
}
因为 WorkProperties 配置类上的
@ConfigurationProperties
注解,所以我们在编译一次该项目后,可以自动通过spring-boot-configuration-processor
依赖生成对应的spring-configuration-metadata.json
配置元数据,路径:target/classes/META-INF/
。
2.3.1 @ConfigurationProperties 也支持添加在方法上
@Configuration
public class DataSourceConfig {
@Bean(name = "ordersDataSource")
@ConfigurationProperties(prefix = "spring.datasource.orders") // 读取 spring.datasource.orders 配置到 HikariDataSource 对象
public DataSource ordersDataSource() {
return DruidDataSourceBuilder.create().build();
}
}
2.4 启动类
在 WorkPropertiesCommandLineRunner 类中,我们测试了使用
@ConfigurationProperties
注解的 WorkProperties 配置类,读取work
配置项的效果。在 ValueCommandLineRunner 类中,我们测试了使用
@Value
注解,读取work
配置项的效果。其中,
@Value
注解是 Spring 所提供,@ConfigurationProperties
注解是 Spring Boot 所提供。
代码如下:
@SpringBootApplication
public class JLab1Application {
public static void main(String[] args) {
// SpringApplication.run 会调用所有实现了 ApplicationRunner、CommandLineRunner 的类的run方法
SpringApplication.run(JLab1Application.class, args);
}
@Component
@Order(2) // 排序:加载顺序
public class WorkPropertiesCommandLineRunner implements CommandLineRunner {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private WorkProperties workProperties;
@Override
public void run(String... args) {
logger.info("goodJobTimes:" + workProperties.getGoodJobTimes());
logger.info("completedJobTimes:" + workProperties.getCompletedJobTimes());
}
}
@Component
@Order(1)
public class ValueCommandLineRunner implements CommandLineRunner {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Value("${work.good-job-times}")
private Integer goodJobTimes;
@Value("${work.completed-job-times}")
private Integer completedJobTimes;
@Override
public void run(String... args) {
logger.info("goodJobTimes:" + goodJobTimes);
logger.info("completedJobTimes:" + completedJobTimes);
}
}
}
2.4.1 启动应用
执行 JLab1Application 的 #main(String[] args) 方法,启动 Spring Boot 应用,启动日志如下,加载顺序与上述代码中 @Order(1)
注解中的设置一致
# ValueCommandLineRunner 日志
2024-06-05T09:34:42.163+08:00 INFO 27384 --- [ main] .JLab1Application$ValueCommandLineRunner : goodJobTimes:100
2024-06-05T09:34:42.163+08:00 INFO 27384 --- [ main] .JLab1Application$ValueCommandLineRunner : completedJobTimes:100
# WorkPropertiesCommandLineRunner 日志
2024-06-05T09:34:42.163+08:00 INFO 27384 --- [ main] lication$WorkPropertiesCommandLineRunner : goodJobTimes:100
2024-06-05T09:34:42.163+08:00 INFO 27384 --- [ main] lication$WorkPropertiesCommandLineRunner : completedJobTimes:100
3. 配置引用
在配置文件中,一个配置项可以引用另外的配置项,进行拼接。
如下所示:
work:
good-job-times: 100 # 特别优秀的完成工作的次数,单位:次。
completed-job-times: 100 # 完成工作的次数,单位:次。
desc: "特别优秀的完成工作 ${work.good-job-times} 次,完成工作 ${work.completed-job-times} 次"
4. 命令行配置
Spring Boot 支持从命令行参数,读取作为配置。
例如,修改服务端口,则会使用
java -jar xxx.jar --server.port=18080
命令,将端口修改为 18080。
通过命令行连续的两个中划线 --
,后面接 配置项=配置值
的方式,修改配置文件中对应的配置项为对应的配置值。
例如,
--配置项=配置值
。如果希望修改多个配置项,则使用多组--
即可。例如说,--配置项1=配置值1 --配置项2=配置值2
。
注:命令行的配置高于配置文件。
5. 多环境配置
在 Spring Boot 的项目开发中,我们会涉及多个不同的环境,部署 Spring Boot 到对应环境时,需要采用不同的配置。
如果只使用一份配置文件,每次部署到不同的环境,就需要重复去修改,显然非常麻烦且容易出错。所以针对多环境场景下,我们会给每个环境创建一个配置文件 application-${profile}.yaml
。其中,${profile}
为环境名,对应到 Spring Boot 项目生效的 Profile。
例如:
application-dev.yaml
配置文件,对应 dev 开发环境。这样,我们在生产环境的服务器上,使用java -jar xxx.jar --spring.profiles.active=prod
命令,就可以加载application-prod.yaml
配置文件,从而连接上配置文件配置的生产环境的 MySQL、Redis 等等服务。
5.1 生成脚手架
项目代码使用 Spring io 脚手架初始化生成
在 pom.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>3.3.0</version>
<relativePath/>
</parent>
<artifactId>jLab-1-demo-profiles</artifactId>
<dependencies>
<!-- 实现对 SpringMVC 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
5.2 配置文件
在 resources
目录下,创建 4 个配置文件,对应不同的环境。如下:
application.yml
,放不同环境的相同配置。
# 多配置文件中的相同配置项
spring:
application:
name:jLab-1-demo-profiles
# application-${profile} 配置文件的优先级更高,会覆盖它
server:
port: 7080
application-local.yml
,本地环境。
server:
port: 8080
application-dev.yml
,开发环境。
server:
port: 8081
application-prod.yml
,生产环境。
server:
port: 8082
5.3 测试
直接运行,日志如下:
2024-06-05T13:57:04.067+08:00 INFO 34144 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 7080 (http)
修改
application.yml
,指定 dev 作为运行环境。
# 多配置文件中的相同配置项
spring:
application:
name:jLab-1-demo-profiles
# 指定配置文件
profiles:
active: dev
# application-${profile} 配置文件的优先级更高,会覆盖它
server:
port: 7080
日志如下:
2024-06-05T13:59:37.037+08:00 INFO 23692 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8081 (http)
修改 IDEA 覆盖配置属性 ,指定运行环境为 prod,旧版本添加
--spring.profiles.active=prod
日志如下:
2024-06-05T14:06:17.024+08:00 INFO 32556 --- [ main] m.j.j.JLab1DemoProfilesApplication : The following 1 profile is active: "prod"
2024-06-05T14:06:17.547+08:00 INFO 32556 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8082 (http)
6. 自定义配置文件
原文中此处的样例在 SpringBoot 3.3.0 版本中未复用成功,此处提供另外一种方式
6.1 生成脚手架
修改 pom 文件,如下:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jLab-1-demo-configname</artifactId>
<dependencies>
<!-- Spring Boot Starter 基础依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
6.2 配置文件
在 resources
目录下,创建两个配置文件。如下:
application.yml
配置内容如下:
application-test: hahaha
rpc.yml
配置内容如下:
rpc-test: yeah
6.3 启动类
此处使用 @PropertySources
加载多个配置文件,在 ValueCommandLineRunner 中,打印了两个配置文件的配置项。
/**
* 读取指定配置文件 @PropertySource / 多个配置文件 @PropertySources
* 可以与下列两个注解搭配使用
* - @ConfigurationProperties(prefix = "work")
* - @Value("${work.good-job-times}")
*/
@SpringBootApplication
@PropertySources({ @PropertySource("classpath:application.yml"),
@PropertySource("classpath:rpc.yml") })
public class JLab1DemoConfignameApplication {
public static void main(String[] args) {
// 启动 Spring Boot 应用
SpringApplication.run(JLab1DemoConfignameApplication.class, args);
}
@Component
public class ValueCommandLineRunner implements CommandLineRunner {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Value("${application-test}")
private String applicationTest;
@Value("${rpc-test}")
private String rpcTest;
@Override
public void run(String... args) {
logger.info("applicationTest:" + applicationTest);
logger.info("rpcTest:" + rpcTest);
}
}
}
运行后,日志如下:
2024-06-05T15:33:04.284+08:00 INFO 12180 --- [ main] ignameApplication$ValueCommandLineRunner : applicationTest:hahaha
2024-06-05T15:33:04.284+08:00 INFO 12180 --- [ main] ignameApplication$ValueCommandLineRunner : rpcTest:yeah
7. 配置加载顺序
命令行参数
特定的应用程序属性,默认如下,详见上方参考文档
当前目录的
/config
子目录当前目录
Classpath
/config
包Classpath 根
打包Jar之外的指定配置文件(
application-{profile}.properties
和 YAML 变体)打包jar之内的指定配置文件(
application-{profile}.properties
和 YAML 变体)@Configuration
个类上的 @PropertySource 条 Comments。默认属性(通过设置
SpringApplication.setDefaultProperties
指定)。