Spring-yml
Spring Boot会从以下位置加载外部配置文件 application.properties/yml,并读取成PropertySources加载到Environment中
读取配置文件顺序
└── spring-boot-project
2 ├── src
3 │ └── main
4 │ ├── java
5 │ │ └── com
6 │ │ └── example
7 │ │ └── demo
8 │ │ └── DemoApplication.java <- Spring Boot 应用的主入口类
9 │ └── resources
10 │ ├── config
11 │ │ └── application.yml <- 第3个位置:类路径下的/config目录
12 │ └── application.properties <- 第4个位置:类路径的根目录
13 └── config
14 └── application.yml <- 第1个位置:入口类的当前目录的/config子目录
15 └── application.properties <- 第2个位置:入口类的当前目录
以此按照顺序读取配置文件的信息,
1.不同位置配置文件有相同属性以优先读取为主
2.不同位置配置文件有不相同的属性会合并有效配置
最终所有这些属性设置都会被读取到Environment,对应用的运行行为进行配置。
application.yml
格式
yyds:
y1: 666
y2: 777
注意,“:”后面有一个空格,这是YAML要求的格式
占位符
app:
name: spring boot in depth
desc: chapter:${app.name} is hard to learn
@SpringBootTest
public class SpringTestC {
@Value("${app.name}")
private String name;
@Value("${app.desc}")
private String desc;
@Test
public void test(){
System.out.println("name:" + name);
System.out.println("desc:" + desc);
}
}
打印结果:
name:spring boot in depth
desc:chapter:spring boot in depth is hard to learn
类型安全的配置属性
前面是通过使用@Value获得配置属性的Spring Boot提供了大量的配置属性,Spring Boot自己是如何获得并使用这些配置属性的呢?
- 加载自动配置:SpringBoot默认的配置文件信息
- 实现自动配置:在原有的基础上进行拓展
@ConfigurationProperties
注解是Spring Boot中用于将外部配置文件中的属性与Java Bean中对应属性进行绑定的关键注解。这个绑定过程是由Spring容器中的一个特殊的BeanPostProcessor
——ConfigurationPropertiesBindingPostProcessor
实现的。
为了让*Properties
类成为一个Bean并参与绑定
方式1:
yyds:
y1: 666
y2: 777
yb: true
@ConfigurationProperties(
prefix = "yyds",
ignoreUnknownFields = true // 忽略未知字段
)
@Component
@Data
@ToString
public class SpringYmlProperties {
private Integer y1;
private Integer y2;
private boolean yb;
}
方式2:
com.example.myapp.properties.database.url=jdbc:mysql://localhost:3306/mydb
com.example.myapp.properties.database.username=root
com.example.myapp.properties.database.password=password
package com.example.myapp.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "com.example.myapp.properties.database")
public class DatabaseProperties {
private String url;
private String username;
private String password;
// Getters and Setters...
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
@SpringBootApplication
@ConfigurationPropertiesScan("com.example.myapp.properties") // 扫描指定包
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
配置文件-松散绑定
Spring Boot提供了一种叫作“松散绑定”的技术,属性可以是“烤串式”、“下画线式”、“驼峰式”或者是“大写字母式”
app:
# 烤串式(kebab-case)
my-config-value: example_value_kebab
# 下划线式(snake_case)
my_config_value: another_example_snake
# 驼峰式(camelCase)
myConfigValue: yet_another_example_camel
#大写字母式
APP_MY_CONFIG_VALUE: final_example
Profile
可以根据不同的环境或条件切换不同的配置。
单文件profile
我们可以在一个application.yml内定义多个Profile,各个Profile之间用“—”隔开。
spring:
profiles: default
datasource:
url: jdbc:mysql://localhost:3306/default_db
username: default_user
password: default_password
---
spring:
profiles: development
datasource:
url: jdbc:mysql://localhost:3306/dev_db
username: dev_user
password: dev_password
---
spring:
profiles: production
datasource:
url: jdbc:mysql://production-db-server:3306/prod_db
username: prod_user
password: prod_password
在上述配置中,default
Profile 是默认配置,当没有激活其他Profile时使用。要激活某个特定Profile,可以通过命令行参数 -Dspring.profiles.active=development
或 -Dspring.profiles.active=production
来指定加载哪个Profile的配置。另外,也可以在代码中通过 @ActiveProfiles
注解来激活指定的Profile。在运行时,Spring Boot会根据激活的Profile加载对应的配置部分
多文件Profile
application-default.yml
(默认环境配置)
spring:
profiles: default
datasource:
url: jdbc:mysql://localhost:3306/default_db
username: default_user
password: default_password
application-development.yml
(开发环境配置)
spring:
profiles: development
datasource:
url: jdbc:mysql://localhost:3306/dev_db
username: dev_user
password: dev_password
application-production.yml
(生产环境配置)
spring:
profiles: production
datasource:
url: jdbc:mysql://production-db-server:3306/prod_db
username: prod_user
password: prod_password
指定多文件方式一:yml手动设置
spring:
profiles:
active: development
指定多文件方式二:xml动态指定
spring:
profiles:
active: @profiles.active@
<project>
...
<profiles>
<profile>
<id>dev</id>
<properties>
<profiles.active>development</profiles.active>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<profiles.active>production</profiles.active>
</properties>
</profile>
</profiles>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering> <!-- 开启资源过滤 -->
</resource>
</resources>
...
</build>
...
</project>
当执行Maven构建时,通过指定 -Pdev
或 -Pprod
参数激活对应的Profile,构建工具会将@profiles.active@
替换为Profile中定义的值,从而达到动态切换Spring Boot Profile的目的
EnvironmentPostProcessor(个人觉得不常用)
Spring Boot提供的一个扩展点,允许开发者在Spring Application Context初始化之前对Environment
对象进行自定义处理。Environment
对象封装了应用运行时的所有环境属性,包括系统属性、命令行参数、属性文件中的配置等。
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
Map<String, Object> map = new HashMap<>();
map.put("my.custom.property", "someValue");
MapPropertySource propertySource = new MapPropertySource("myCustomPropertySource", map);
environment.getPropertySources().addFirst(propertySource);
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE; // 设置执行顺序
}
}
org.springframework.boot.env.EnvironmentPostProcessor=com.example.MyEnvironmentPostProcessor