SpringBoot 配置文件
配置文件
Spring Boot 提供了大量的自动配置,极大地简化了spring 应用的开发过程,当用户创建了一个 Spring Boot 项目后,即使不进行任何配置,该项目也能顺利的运行起来。当然,用户也可以根据自身的需要使用配置文件修改 Spring Boot 的默认设置。
SpringBoot 默认使用以下 2 种全局的配置文件,其文件名是固定的。
1、application.properties
2、application.yml
其中,application.yml 是一种使用 YAML 语言编写的文件,它与 application.properties 一样,可以在 Spring Boot 启动时被自动读取,修改 Spring Boot 自动配置的默认值。
下面我们将详细介绍 YAML 语言的语法及使用。
YAML 简述
字母
YAML(YAML Ain’t Markup Language)
- YAML is A Markup Language 是一个标标记语言
- YAML isn't Markup Language 不是一个标签语言
名称
YAML 全称 YAML Ain't Markup Language,它是一种以数据为中心的标记语言,比 XML 和 JSON 更适合作为配置文件。
想要使用 YAML 作为属性配置文件(以 .yml 或 .yaml 结尾),需要将 SnakeYAML 库添加到 classpath 下,Spring Boot 中的 spring-boot-starter-web 或 spring-boot-starter 都对 SnakeYAML 库做了集成, 只要项目中引用了这两个 Starter 中的任何一个,Spring Boot 会自动添加 SnakeYAML 库到 classpath 下。
优势
1、以数据为中心
2、比xml、json更简洁
xml
<server>
<port>
8080
</port>
</server
json
{
"server.port": 8080
}
yaml
server:
port: 8080
YAML语法
说明
使用缩进来表示层级关系
缩进时不允许使用tab键,而是使用空格
缩进的空格数目不重要,只要相同级别的元素左侧对齐即可
大小写敏感
K:(空格) V表示一对键值对,注意空格必须要有
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.01:3306/studb
username: root
password: root
数据结构
YAML 支持以下三种数据结构:
1、字面量:单个的、不可拆分的值
2、对象和Map:键值对的集合
3、数组、List和Set:一组按次序排列的值
字面量
字面量是指单个的,不可拆分的值,例如:数字、字符串、布尔值、以及日期等。
字面量直接写在键值对的“value”中即可,且默认情况下字符串是不需要使用单引号或双引号的。
" "双引号:不会转义字符串的特殊字符,特殊字符会作为本身的作用输出
name: "zhang n lisli" //输出 zhang 换行 lisli
' ' 单引号,则会转义字符中的特殊字符,输出的只是字符串内容
name: 'zhang n lisli' //输出 zhang n lisli
对象、Map
user:
id: 1001
name: zs
行内写法
user:{id: 1001, name: zs}
数组 、List和Set
用 - 空格 表示数组中的一个值
hobby:
- swim
- game
- sport
行内
hobby: [swim,game,sport]
文档隔离
一个 YAML 文件可以由一个或多个文档组成,文档之间使用“---”作为分隔符,且个文档相互独立,互不干扰。如果 YAML 文件只包含一个文档,则“---”分隔符可以省略。
---
website:
name: wanho
url: www.wanho.net
---
website: {name: wanho,url: www.wanho.net}
pets:
- dog
- cat
- pig
---
pets: [dog,cat,pig]
name: "zhangsan n lisi"
---
name: 'zhangsan n lisi'
配置文件占位符,properties和yml都支持
${random.value}
${random.uuid}
${random.int}
${random.long}
${random.int(10)}
${random.int[1024,2408]}
${对象.属性:默认值}
application.yml
person:
first-name: 'san n feng'
last-name: zhang${random.uuid}
handsome: true
age: ${random.int[1,100]}
birth: 2018/8/8
maps: {k1: v1,k2: v2}
lists: [a,b,c]
dog:
name: ${person.last-name:张}-旺财
age: 10
配置文件位置
默认配置文件
通常情况下,Spring Boot 在启动时会将 resources 目录下的 application.properties 或 apllication.yml 作为其默认配置文件,我们可以在该配置文件中对项目进行配置,但这并不意味着 Spring Boot 项目中只能存在一个 application.properties 或 application.yml。
Spring Boot 项目中可以存在多个 application.properties 或 apllication.yml。
Spring Boot 启动时会扫描以下 5 个位置的 application.properties 或 apllication.yml 文件,并将它们作为 Spring boot 的默认配置文件。
1、file:./config/
2、file:./config/*/
3、file:./
4、classpath:/config/
5、classpath:/
注:file: 指当前项目根目录;classpath: 指当前项目的类路径,即 resources 目录。
以上所有位置的配置文件都会被加载,且它们优先级依次降低,序号越小优先级越高。其次,位于相同位置的 application.properties 的优先级高于 application.yml。
所有位置的文件都会被加载,高优先级配置会覆盖低优先级配置,形成互补配置,即:
- 存在相同的配置内容时,高优先级的内容会覆盖低优先级的内容;
- 存在不同的配置内容时,高优先级和低优先级的配置内容取并集。
外部配置文件
除了默认配置文件,Spring Boot 还可以加载一些位于项目外部的配置文件。我们可以通过如下 2 个参数,指定外部配置文件的路径:
- spring.config.location
- spring.config.additional-location
spring.config.location
我们可以先将 Spring Boot 项目打包成 JAR 文件,然后在命令行启动命令中,使用命令行参数 --spring.config.location,指定外部配置文件的路径。
java -jar {JAR} --spring.config.location={外部配置文件全路径}
需要注意的是,使用该参数指定配置文件后,会使项目默认配置文件(application.properties 或 application.yml )失效,Spring Boot 将只加载指定的外部配置文件。
1、在本地目录 D:myConfig 下,创建一个配置文件 my-application.yml,配置如下。
#指定配置文件
server:
port: 8088
2、打开命令行窗口,跳转到 JAR 文件所在目录,执行以下命令,其中 --spring.config.location 用于指定配置文件的新位置。
java -jar springbootdemo-0.0.1-SNAPSHOT.jar --spring.config.location=D:myConfigmy-application.yml
spring.config.additional-location
我们还可以在 Spring Boot 启动时,使用命令行参数 --spring.config.additional-location 来加载外部配置文件。
java -jar {JAR} --spring.config.additional-location={外部配置文件全路径}
但与 --spring.config.location 不同,--spring.config.additional-location 不会使项目默认的配置文件失效,使用该命令行参数添加的外部配置文件会与项目默认的配置文件共同生效,形成互补配置,且其优先级是最高的,比所有默认配置文件的优先级都高。
将 springbootdemo 打包为 JAR 文件,打开命令行窗口,跳转到该项目 JAR 所在目录下,执行以下命令启动该项目。
java -jar springbootdemo-0.0.1-SNAPSHOT.jar --spring.config.additional-location=D:myConfigmy-application.yml
注意:Maven 对项目进行打包时,位于项目根目录下的配置文件是无法被打包进项目的 JAR 包的,因此位于根目录下的默认配置文件无法在 JAR 中生效,即该项目将只加载指定的外部配置文件和项目类路径(classpath)下的默认配置文件,它们的加载优先级顺序为:
a、spring.config.additional-location 指定的外部配置文件 my-application.yml
b、classpath:/config/application.yml
c、classpath:/application.yml
根据配置文件优先级分析可知:
- 以上三个配置文件中 my-application.yml 的优先级最高,因此该项目的服务器端口号为 “8088”;
- 只有 classpath:/config/application.yml 中配置了上下文路径(context-path),因此该项目的上下文路径为 “/helloworld”;
- 基于以上配置分析,得出该项目访问路径为“http://localhost:8088/helloWorld”。
通过上面的示例,我们看到将 Spring Boot 项目打包后,然后在命令行启动命令中添加 spring.config.additional-location 参数指定外部配置文件,会导致项目根目录下的配置文件无法被加载,我们可以通过以下 3 种方式解决这个问题。
在 IDEA 的运行配置(Run/Debug Configuration)中,添加虚拟机参数 -Dspring.config.additional-location=D:myConfigmy-application.yml,指定外部配置文件;
- 在 IDEA 的运行配置(Run/Debug Configuration)中,添加程序运行参数 --spring.config.additional-location=D:myConfigmy-application.yml,指定外部配置文件;
- 在主启动类中调用 System.setProperty()方法添加系统属性 spring.config.additional-location,指定外部配置文件。
4.3 配置文件加载顺序
-
在文档的24. Externalized Configuration小节,标记着有17种
-
profile
- 外部
- 内部
-
不带profile
- 外部
- 内部
获取配置文件内容
所谓“配置绑定”就是把配置文件中的值与 JavaBean 中对应的属性进行绑定。通常,我们会把一些配置信息(例如,数据库配置)放在配置文件中,然后通过 Java 代码去读取该配置文件,并且把配置文件中指定的配置封装到 JavaBean(实体类) 中。
SpringBoot 提供了以下 2 种方式进行配置绑定:
- 使用 @ConfigurationProperties 注解
- 使用 @Value 注解
@ConfigurationProperties 使用
通过 Spring Boot 提供的 @ConfigurationProperties 注解,可以将全局配置文件中的配置数据绑定到 JavaBean 中,下面演示如何通过 @ConfigurationProperties 注解进行配置绑定。
通过Spring Initializer 新建一个项目,选中Lombok、Web
新建po下的两个类
Dog.java
@Data
public class Dog {
private String name;
private Integer age;
}
Person.java
@Data
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String firstName;
private String lastName;
private Integer age;
private boolean handsome;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}
注意:
- 只有在容器中的组件,才会拥有 SpringBoot 提供的强大功能。如果我们想要使用 @ConfigurationProperties 注解进行配置绑定,那么首先就要保证该对 JavaBean 对象在 IoC 容器中,所以需要用到 @Component 注解来添加组件到容器中。
- JavaBean 上使用了注解 @ConfigurationProperties(prefix = "person") ,它表示将这个 JavaBean 中的所有属性与配置文件中以“person”为前缀的配置进行绑定。
- 在全局配置文件中设置值
application.properties
# server.port=8088
# server.servlet.context-path= /config
# person.first_name=san
# person.lastName=zhang
# person.age=18
# person.handsome=true
# person.birth=2019/2/27
# person.maps.k1=v1
# person.maps.k2=v2
# person.lists=a,b,c
# person.dog.name=旺财
# person.dog.age=18
- 注意properties的编码格式要为UTF-8的格式
appliction.yml
server:
port: 8099
servlet:
context-path: /config
person:
first-name: 'san n feng'
last-name: zhang
handsome: true
age: 20
birth: 2018/8/8
maps: {k1: v1,k2: v2}
lists: [a,b,c]
dog:
name: 旺财
age: 10
- 测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
@Autowired
private Person person;
@Test
public void test1() {
System.out.println(person);
}
}
@Value注解的方式
@Data
@Component
//@ConfigurationProperties(prefix = "person")
//启用验证
@Validated
public class Person {
@Value("${person.first-name}")
//必须是邮箱格式
//@Email
private String firstName;
private String lastName;
@Value("#{${person.age}*2}")
private Integer age;
@Value("${person.handsome}")
private boolean handsome;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}
两种方式对比
@ConfigurationProperties | @Value | |
---|---|---|
位置 | 标注在JavaBean的类名上 | 标注在JavaBean的属性上 |
功能 | 批量注入配置文件中的属性值 | 一个个指定值 |
松散语法 | Person类firstName属性: person.firstName、person.file-name、person-first_name |
不支持 |
复杂类型 | 支持所有类型。Map、List、Set和对象等 | 只支持基本数据类型, 例如字符串、布尔值、整数值 |
SPEL | 不支持 | 支持 |
验证 | 支持 | 不支持 |
结论
两个注解之间,并没有明显的优劣之分,它们只是适合的应用场景不同而已,根据实际应用场景选择合适的注解能达到事半功倍的效果。
- 如果编写了一个JavaBean的类,属性都要从配置文件中获取值,推荐使用@ConfigurationProperties
- 如果只是想访问配置文件中的某个值,则使用@Value, 例如数据库的配置文件读取
@PropertySource
如果将所有的配置都集中到 application.properties 或 application.yml 中,那么这个配置文件会十分的臃肿且难以维护,因此我们通常会将与 Spring Boot 无关的配置(例如自定义配置)提取出来,写在一个单独的配置文件中,并在对应的 JavaBean 上使用 @PropertySource 注解指向该配置文件。
将与 person 相关的自定义配置移动到 src/main/resources 下的 person.properties 中(注意,必须把 application.properties 或 application.yml 中的相关配置删除),如下图。
指定自定义的属性配置文件,且配置文件的后缀名必须为.properties
@Data
@Component
@PropertySource(value = {"classpath:person.properties"})
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
//@Value("${person.first-name}")
//@Email
private String firstName;
private String lastName;
//@Value("#{${person.age}*2}")
private Integer age;
//@Value("${person.handsome}")
private boolean handsome;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}
resources/persion.properties
person.first_name=san
person.lastName=zhang
person.age=18
person.handsome=true
person.birth=2019/2/27
person.maps.k1=v1
person.maps.k2=v2
person.lists=a,b,c
person.dog.name=旺财
person.dog.age=18
7导入配置文件
默认情况下,Spring Boot 中是不包含任何的 Spring 配置文件的,即使我们手动添加 Spring 配置文件到项目中,也不会被识别。那么 Spring Boot 项目中真的就无法导入 Spring 配置吗?答案是否定的。
Spring Boot 为了我们提供了以下 2 种方式来导入 Spring 配置:
- 使用 @ImportResource 注解加载 Spring 配置文件
- 使用全注解方式加载 Spring 配置
@ImportResource
- 导入自定义的spring-xml的配置文件
- Application.java
//导入自定义的配置文件
@ImportResource(locations ="classpath:spring.xml")
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
resources/spring.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="net.wanho.service.HelloService"></bean>
</beans>
@Bean
在SpringBoot中不推荐使用xml配置的方式,而是使用@Bean注解的方式
在net.wanho的包下,新建一个类config.MyAppConfig.java,通过@Bean的方式创建了对象,测试方法与上面一致
/*
* 配置类*/
@Configuration
public class MyAppConfig {
//创建一个service的对象,名称默认为方法名
@Bean
public HelloService helloService2(){
return new HelloService();
}
}
还没有人赞赏,快来当第一个赞赏的人吧!
- 2¥
- 5¥
- 10¥
- 20¥
- 50¥
声明:本文为原创文章,版权归信息岛所有,欢迎分享本文,转载请保留出处!