在日常开发中我们有一些配置是不能写死在代码里的,因为他们有变化的可能。比如服务地址,dev,test,pre ,product 每个环境的地址肯定都是不一致的。而这些变量我们怎么来处理呢。就是将其定义到properties文件中。
配置定义
spring boot 支持2种类型的配置文件。
properties
properties为键值对的配置方式,没有层级关系,一个key 对应一个value;
示例
spring.application.name=hello-world
spring.application.index=${random.int}
yml
yml是一种有层级结构的书写配置文件的方式
示例
spring:
application:
name: hello-world
index: ${random.int}
虽然yml看上去优雅一点,但是如果层级关系过多,可读性下降的会比较快。注意使用yml配置 “:” 后边必须有一个空格.
配置取值
value注解
@Value(value = "${spring.application.name}")
@Value(value = "${spring.application.index:0}")
@Value(value = "#{'${spring.application.name}'.length()}")
${spring.application.name}
这种配置方式要求程序在启动时必须能获取到这个配置信息。一般是properties或者yml文件中必须要有该配置,当然其他配置位置也行。
${spring.application.index:0}
相对于上面的配置方式就是给属性设置了一个默认值,即:后面的值,这样程序启动就不会报错,而是使用默认值。使用该方式要一定要小心,因为有将默认值得发布至生产环境的可能。
#{'${spring.application.name}'.length()}
#后面是一个表达式,可以给属性注入一个表达式的结果。
ConfigurationProperties注解
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "spring.application")
public class ApplicationConfig {
private String name;
private int index;
private int appNameLength;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public int getAppNameLength(){
return this.name.length();
}
}
@ConfigurationProperties(prefix = "spring.application")
用这个注解能抽象出一个类。完成属性的注入。这样在需要使用该配置时使用@Autowired
注解获得该对象。
ps:这两种方式都能完成资源的注入那我们怎么选择呢?我的建议是,如果这个配置仅在1个类中使用时使用Value注解进行,如果这个配置在多个类中使用使用ConfigurationProperties注解。保证如果要变更1个配置名只修改1个位置。减少出错的可能。
各个环境激活
上面说过我们把这些信息抽象成配置就是因为这些东西可能随着环境不同的变化而变化。那我们怎么选择适当的环境呢。
首先我们根据不同的环境建立多个配置文件。如图
image.png
以dev为例
spring.application.name=hello-world-dev
spring.application.index=${random.int}
里面配置的是该环境下的配置信息。我们在启动程序的时候使用启动参数来决定使用那套配置。
java -jar hello-wrold-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
如果我们本地调试要怎么切换环境呢。
1.在文件中 application.properties 增加 spring.profiles.active=dev 配置
2.修改idea Run/Debug Configurations 如图
如果使用2方法,还可以设置VM options 来进行设置。但是设置方式是
-Dspring.profiles.active=dev
而不是--如果对应到启动命令为
java -jar -Dspring.profiles.active=dev hello-wrold-0.0.1-SNAPSHOT.jar
因为设置的是jvm 的参数所有要跟在java
后面。
随机数配置
my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}
配置获取方式及其优先级
1.Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
2.@TestPropertySource annotations on your tests.
3.@SpringBootTest#properties annotation attribute on your tests.
4.Command line arguments.
5.Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property).
6.ServletConfig init parameters.
7.ServletContext init parameters.
8.JNDI attributes from java:comp/env.
9.Java System properties (System.getProperties()).
10.OS environment variables.
11.A RandomValuePropertySource that has properties only in random.*.
12.Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants).
13.Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants).
14.Application properties outside of your packaged jar (application.properties and YAML variants).
15.Application properties packaged inside your jar (application.properties and YAML variants).
16.@PropertySource annotations on your @Configuration classes.
17.Default properties (specified by setting SpringApplication.setDefaultProperties).
优先级是由高到低。其实这中间大多数我们都不常用,在日常工作中最主要的是4.命令行参数,10系统环境变量。 12.外部application-{profile}.properties配置文件,13.application-{profile}.properties 内部配置文件。
结果演示
image.png示例代码:https://github.com/tong467/hello-wrold
参考文献:https://docs.spring.io/spring-boot/docs/2.0.0.BUILD-SNAPSHOT/reference/htmlsingle/#boot-features-external-config-random-values
网友评论