我们在使用springboot
开发的时候,经常会从外部获取属性值,为了记住这些规则,特此做如下记录~~~
一、为什么要做外部化配置
- 本地开发的时候,上传文件的时候,每个人想上传的路径不一样,使用外部配置,就可以单独设置自己的上传路径
- 项目部署的时候,不同的环境使用不同的配置,使用外部挂载配置这样我们就可以为每个环境单独设置一份配置。
二、springboot官方的解释
Spring Boot lets you externalize your configuration so that you can work with the same application code in different environments. You can use properties files, YAML files, environment variables, and command-line arguments to externalize configuration. Property values can be injected directly into your beans by using the @Value
annotation, accessed through Spring’s Environment
abstraction, or be bound to structured objectsthrough @ConfigurationProperties
.
Spring Boot uses a very particular PropertySource
order that is designed to allow sensible overriding of values. Properties are considered in the following order:
Spring Boot允许您外部化您的配置,以便您可以在不同的环境中使用相同的应用程序代码。您可以使用属性文件、YAML文件、环境变量和命令行参数来具体化配置。属性值可以通过使用@Value注释直接注入到bean中,通过Spring的环境抽象进行访问,或者通过@ConfigurationProperties绑定到结构化对象。
Spring Boot使用一个非常特殊的PropertySource顺序,旨在允许合理的值重写。属性按以下顺序考虑:
- 开发者工具 Devtools全局配置参数
在IDEA或Eclipse中,安装并启用Spring Boot Devtools插件。打开项目的Settings(或Preferences),在Build, Execution, Deployment下面的Compiler中找到Build process VM options, 在后面的文本框中输入 devtools 全局配置参数(如:-Dspring.devtools.restart.pollInterval=3000 )即可。
- 单元测试上的@TestPropertySource注解指定的参数
在测试类中使用@TestPropertySource注解指定测试时使用的配置文件(如:@TestPropertySource(locations = "classpath:test.properties"))。
- 单元测试上的@SpringBootTest注解指定的参数
在SpringBoot测试类中使用@SpringBootTest注解指定测试时使用的配置文件和其他的属性(如:@SpringBootTest(properties = {"test.name=test", "test.age=18"}))。
- 命令行指定的参数,如java -jar springboot.jar --name="xxx"
在命令行中启动应用程序时,指定需要覆盖的属性参数(如:java -jar springboot.jar --name="xxx")。
- 命令行中的SPRING_APPLICATION_JSON指定参数,如java -Dspring.application.json='{"name":"xxx"}' -jar springboot.jar
在命令行中启动应用程序时,使用SPRING_APPLICATION_JSON来传递JSON格式的参数(如:java -Dspring.application.json='{"name":"xxx"}' -jar springboot.jar)。
- ServletConfig初始化参数
在Servlet的初始化方法中,使用getInitParameter方法获取参数(如:String name = config.getInitParameter("name"))。
- ServletContext初始化参数
在Servlet的初始化方法中,使用getServletContext().getInitParameter方法获取参数(如:String name = config.getServletContext().getInitParameter("name"))。
- JNDI参数(如java:comp/env/spring.application.json)
使用JNDI API 来获取参数,如:InitialContext context = new InitialContext(); String name = (String) context.lookup("java:comp/env/spring.application.json");
- Java系统参数(来源:System.getProperties())
使用System.getProperties()方法来获取Java系统参数(如:String name = System.getProperties().getProperty("name"))。
- 操作系统环境变量参数
使用System.getenv()方法来获取操作系统环境变量参数(如:String name = System.getenv("name"))。
- RandomValuePropertySource随机数,仅匹配:ramdom.*
在配置文件中使用以"random."开头的属性名称,Spring Boot会自动替换该属性的值为对应的随机数。
- JAR包外面的配置文件参数(application-{profile}.properties/yaml)
在项目的配置文件夹下新建对应的配置文件(如:application-dev.properties),并在该文件中设置需要的属性信息。
- JAR包里面的配置文件参数(application-{profile}.properties/yaml)
在JAR包内部,新建resources文件夹,然后在该文件夹下新建对应的配置文件(如:application-prod.properties)。
- JAR包外面的配置文件参数(application.properties/yaml)
在项目的配置文件夹下新建application.properties或application.yaml文件,并在该文件中设置需要的属性信息。
- JAR包里面的配置文件参数(application.properties/yaml)
在JAR包内部,新建resources文件夹,然后在该文件夹下新建application.properties或application.yaml文件,并在该文件中设置需要的属性信息。
- @Configuration配置文件上@PropertySource注解加载的参数
在@Configuration注解的Java类上,添加@PropertySource注解指定属性文件的路径(如:@PropertySource("classpath:test.properties"))。
- 默认参数(通过SpringApplication.setDefaultProperties指定)
在启动Spring Boot应用程序时,通过SpringApplication.setDefaultProperties指定默认的配置属性(如:SpringApplication.setDefaultProperties(Collections.singletonMap("name", "default")))。
我们常用的方式有如下几种:
calsspath
类路径下的配置文件
. project-sample
├── config
│ ├── application.yml (4)
│ └── src/main/resources
| │ ├── application.yml (1)
| │ └── config
| | │ ├── application.yml (2)
├── application.yml (3)
注:src/main/resources下的配置文件在项目编译时,会放在target/classes下
启动时加载配置文件顺序:1 -> 2 -> 3 -> 4
,优先级 4 > 3 > 2 > 1
idea
中指定配置文件--spring.config.location
在Configurations
中的Program arguments
指定加载外部配置文件,使用--spring.config.location
指定/yml/application.yml
下的文件
java -jar
命令指定配置文件java -jar -Dspring.config.location
或者属性java -jar springboot.jar --name="xxx"
比如说,我们使用docker
部署项目的时候,我们可以使用java -jar -Dspring.config.location=/admin/yml/application.yml
指定加载外部的配置,而不使用jar里面的
docker run --privileged -d -p 58070:8799 --name cic-admin openjdk:11 java -jar -Dspring.config.location=/admin/yml/application.yml -Dfile.encoding=UTF-8 -Duser.timezone=GMT+08 /admin/jar/cic-admin.jar
- JAR包外面的配置文件
其中文件结构如下:
├── config
│ ├── application.yml (2)
├── application.yml (1)
├── springbootDemo-0.0.1-SNAPSHOT.jar
当我们执行java -jar springbootDemo-0.0.1-SNAPSHOT.jar
会使用config
目录下的yml
文件,如果config
下不存在,则使用jar
同级的文件