SpringBoot配置
读取配置文件的三种方式
a. Environment 读取
所有的配置信息,都会加载到Environment实体中,因此我们可以通过这个对象来获取系统的配置,通过这种方式不仅可以获取application.yml
配置信息,还可以获取更多的系统信息
@RestController
public class DemoController {
@Autowired
private Environment environment;
@GetMapping(path = "show")
public String show() {
Map<String, String> result = new HashMap<>(4);
result.put("env", environment.getProperty("server.port"));
return JSON.toJSONString(result);
}
}
b. @Value 注解方式
@Value
注解可以将配置信息注入到Bean的属性,也是比较常见的使用方式,但有几点需要额外注意
- 如果配置信息不存在会怎样?
- 配置冲突了会怎样(即多个配置文件中有同一个key时)?
使用方式如下,主要是通过 ${}
,大括号内为配置的Key;如果配置不存在时,给一个默认值时,可以用冒号分割,后面为具体的值
@RestController
public class DemoController {
// 配置必须存在,且获取的是配置名为 app.demo.val 的配置信息
@Value("${app.demo.val}")
private String autoInject;
// 配置app.demo.not不存在时,不抛异常,给一个默认值data
@Value("${app.demo.not:dada}")
private String notExists;
@GetMapping(path = "show")
public String show() {
Map<String, String> result = new HashMap<>(4);
result.put("autoInject", autoInject);
result.put("not", notExists);
return JSON.toJSONString(result);
}
}
c. 对象映射方式
上面的两种方式对于某几个特别的配置来说,一个一个的写还好,如果配置特别多时,每一个都去这么玩,估计会敲的键盘原地爆炸了,当然这么不友好的事情,怎么能忍!因此就有了下面这种使用方式
@Data
@Component
@ConfigurationProperties(prefix = "app.proper")
public class ProperBean {
private String key;
private Integer id;
private String value;
}
多环境配置
1. 多环境选择
a. 命令规则
配置文件,一般要求是以 application
开头,可以是yml文件也可以是properties文件
b. 配置选择
如何确定哪个配置配置文件(application-dev.yml 与 application-pro.yml)生效呢?
- 通过配置信息
spring.profile.active
来指定需要加载的配置文件
通常这个配置信息会放在 applicatin.yml
文件中,如下
spring:
profiles:
active: dev
上面这个表示,当前的配置信息,会从 application.yml
和 application-dev.yml
文件中获取;且-dev
文件中定义的配置信息,会覆盖前面的配置信息
注意
- 上面这个配置的value,可以指定多个配置文件,用英文逗号分隔
- 其中最右边的优先级最高,覆盖左边配置文件中重名的配置信息
2. 优先级问题
上面虽然看是实现了多环境的配置问题,但看完之后有一个明显的疑问,选择环境的配置信息写死在application.yml
文件中,难道说部署到测试和生产环境时,还得记得手动改这个配置的值么?
如果是这样的话,也太容易出问题了吧。。。
那么如何解决这个问题呢,常见的一种方式是通过启动脚本,传入当前环境的参数,来覆盖选中的环境
a. 配置文件优先级
默认的配置文件是放在 src/main/resources
目录下,当然也是可以放其他位置的
- 外置,在相对于应用程序运行目录的
/config
子目录中 - 外置,在应用程序运行的目录中
- 内置,放在config包下(即 src/main/resources/config)目录下
- 内置,放在classpath根目录下(即默认的 src/main/resources/目录下)
上面的优先级是从高到低来的,即外置的改与内置的;config下面的高于根目录下的
以内置的两个进行对比,实测结果如下
b. 配置信息来源
前面一篇中,遗留了一个问题,就是在配置文件中配置了属性 user.name = 一灰灰blog
, 但是实际取出的却是 user
(我个人的电脑用户名),也就是说,Environment中读取的配置信息,不仅仅是从配置文件中获取,还要其他的一些配置信息来源
根据优先级对属性来源进行排序,如下
-
根目录下的开发工具全局设置属性(当开发工具激活时为~/.spring-boot-devtools.properties)。
-
测试中的@TestPropertySource注解。
-
测试中的@SpringBootTest#properties注解特性。
-
命令行参数
-
SPRING_APPLICATION_JSON中的属性(环境变量或系统属性中的内联JSON嵌入)。
-
ServletConfig初始化参数。
-
ServletContext初始化参数。
-
java:comp/env里的JNDI属性
-
JVM系统属性
-
操作系统环境变量
-
随机生成的带random.* 前缀的属性(在设置其他属性时,可以应用他们,比如${random.long})
-
应用程序以外的application.properties或者appliaction.yml文件
-
打包在应用程序内的application.properties或者appliaction.yml文件
-
通过@PropertySource标注的属性源
-
默认属性(通过SpringApplication.setDefaultProperties指定).
iaction.yml文件
-
打包在应用程序内的application.properties或者appliaction.yml文件
-
通过@PropertySource标注的属性源
-
默认属性(通过SpringApplication.setDefaultProperties指定).
原文:https://spring.hhui.top/spring-blog/2018/09/22/180922-SpringBoot%E5%9F%BA%E7%A1%80%E7%AF%87%E9%85%8D%E7%BD%AE%E4%BF%A1%E6%81%AF%E4%B9%8B%E9%85%8D%E7%BD%AE%E5%88%B7%E6%96%B0/