jar包或者镜像已经打完了,想修改下服务的配置,如何实现? ⇒ 临时属性
如修改服务的端口:
java –jar springboot.jar --server.port=80
携带多个属性启动SpringBoot,属性间使用空格分隔
:
java –jar springboot.jar --server.port=80 --spring.datasource.druid.password = admin123
以上能生效的原因,是因为命令行的参数优先级高于配置文件,配置文件中的配置被覆盖,关于优先级,可查看这里:
临时属性添加方式:java –jar 工程名.jar –-属性名=值
设置无效(不会报错)
而在IDEA中,想加临时属性可以编辑配置,修改Environment.Program.arguments
上面的这个参数,会被读取到程序启动的main方法参数args中:
因此,也可以在这里以代码的形式加入相关参数。
public static void main(String[] args) {
String[] arg = new String[1];
arg[0] = "--server.port=8080";
SpringApplication.run(SSMPApplication.class, arg);
}
但为了安全性,一般在启动boot程序时断开读取外部临时配置对应的入口,也就是run方法不传args参数。
public static void main(String[] args) {
SpringApplication.run(SSMPApplication.class); //不传args
}
对于开发自己调试的配置和上线后的配置,参数值不同,特别的,对于一些涉密系统,如银行系统,数据库信息在开发阶段更不可能拿到,另外,总不能每次启动都像上面加参数用临时属性来覆盖,再者数据库信息总不能被丢到外面的参数里吧,因此出现配置文件的4级分类,给不同阶段的人使用。
1级: file :config/application.yml 【最高】
2级: file :application.yml
3级:classpath:config/application.yml
4级:classpath:application.yml 【最低】
其中:
关于各级的位置:
而工程路径file,即和jar包或者模块目录同级的目录:
多层级配置文件间的属性采用叠加并覆盖的形式作用于程序,即不同的取并集,相同的按优先级来覆盖。
既然工程路径file,是和jar包或者模块目录同级的目录,那我在项目project目录下建个application.yml文件,岂不是成了所有模块的公共配置了?
这一点以后应该用得到!!
除了以上配置,也可以自定义配置文件,properties与yml文件格式均支持,如:
然后通过启动参数加载配置文件(无需书写配置文件扩展名):
也可通过配置文件位置–spring.config.location来生效:
有多个配置文件时,逗号隔开就好。
实际开发中,生产、测试、开发三个环境配置各不相同,因此要进行多环境的配置开发:
yml文件写法:使用三个横线来分割文件
含义解释:
按上面,所有环境的配置写在一起,拿分隔符分开,显然不合理,继续做改善:
若使用properties文件来进行多环境启动,则需要多文件,注意文件命名:
include:
根据功能对配置文件中的信息进行拆分,并制作成独立的配置文件,如:
此时,写主配置文件就使用include属性在激活指定环境的情况下,同时对多个环境进行加载使其生效,多个环境间使用逗号分隔
spring:
profiles:
active: dev
include: devDB,devRedis,devMVC
此时,加载了四个文件,即application-dev.yml带下面的这三个,当这四个文件有属性设置冲突时,以后面的为准,最后加载的环境属性生效。
group:
上面的include的写法,有个不好的体验,我从dev切到test,那除了active字段外,include字段的所有值都给改一遍,繁琐,因此,从Spring2.4版开始使用group属性替代include属性,降低了配置书写量
spring:
profiles:
active: dev
group:
"dev": devDB,devRedis,devMVC
"pro": proDB,proRedis,proMVC
"test": testDB,testRedis,testMVC
此时,切环境就只改active字段就好。
写到这儿,想起之前有个需求,要在配置里适配Redis的三种模式的连接,即单机、集群、哨兵。当时想着在一个yaml中去实现,但yaml是文本语言,没法if判断,因此以为不能实现,现在引入include,就可以实现一个服务同时适配三种Redis的连接模式
。
在主配置中include一个文件名带变量的动态文件,变量值由一个环境变量控制且给个默认值。目前项目使用k8s部署,那就在deploy中加一个环境变量。改这个环境变量就实现了切换redis模式。
当然,SpringBoot还有
spring:
config:
import:
# 导入classpath下default目录下的default.properties配置文件
- classpath:/default/default.properties
nacos还有shared-configs
:
spring:
cloud:
nacos:
config:
server-addr: localhost:8848
file-extension: yml
shared-configs:
- application-dev.yml
namespace: dev
以及官网的其他引入配置的方式,都是实现思路。
当maven的pom文件中也配置了多环境开发,且与SpringBoot冲突,如一个默认测试,一个默认开发,此时以Maven为主:
实现兼容:
Tip1:
有的引用Maven属性仍然用dollar大括号:
此时直接打包,Maven指令执行结束后,生成jar包,但类参与了编译而配置文件没有参与编译,而是复制到包中,${}未被解析
Tip2:改完activeByDefault后,即使maven clean,active的文件也不对
基于SpringBoot读取Maven配置属性的前提下,如果在Idea下测试工程时,pom.xml每次更新后,需要手动执行compile
(编译)方可生效