一文搞懂 spring boot 加载外部配置文件

Spring boot 配置文件场景分析

默认情况下如果将spring boot项目,打包成一个fat jar,基本不存在读取外在配置文件的问题,因为 src/main/resources/的yaml或者properties文件,都会打进 jar 内。那如果我们想读取jar外的配置文件该如何做呢?

Spring boot 配置文件优先级

(1) 打包后的 Jar 包以外的 application-.properties;

(2) 打包后的 Jar 包以外的 application.properties;

(3) Jar 包内部的 application-.properties;

(4) Jar 包内部的 application.properties。

可以看到 Jar 包外部的文件比内部的优先级高,特定 Profile 的文件比公共的文件优先级高

指定 profile + 读取外部配置文件

1,当前目录的 /config 子目录;

2,当前目录;

3,CLASSPATH 中的 /config 目录;

4,CLASSPATH 根目录。

也就是说,如果要读取任何外部文件,不需要额外加任何参数,只需要在jar同级目录下,新建一个config目录,然后把配置文件放进去即可,这样spring boot读取到后,会自动将其中的内容添加到 Spring 的 Environment 中。

如果搭配上指定profile的方式,就可以在存在多份profile的前提下,实现精确读取外部配置文件:

#方法一: 如下参数顺序无关
java  -jar -Dspring.profiles.active=test  xxx.jar
java -Dspring.profiles.active=test  -jar  xxx.jar

#方法二: 或使用环境变量
export SPRING_PROFILES_ACTIVE=test
java -jar xxx.jar

改变主配置文件名

默认情况下,主配置文件名为 [ application 或 application- ],但如果你想改变这个值,也可以的,可以使用如下方式:

java -jar foo.jar --spring.config.name=spring

这样的话,你的 jar 同级目录下,可以存在多个以 spring 开头的 profile ,如下:

spring-dev.yaml
spring-test.yaml
spring-prod.yaml

改变默认配置加载路径

大多时候,知道了上面的几种使用方法后,基本解决 90% 的配置加载问题了,但有些时候,你不想使用spring boot 默认的配置文件加载优先级,该怎么办呢?

spring.config.location

参数用于指定查找配置文件的路径,默认是下面这样的,用逗号分隔,越靠后的优先级越高:

classpath:/,classpath:/config/,file:./,file:./config/*/,file:./config/

spring.config.location可以指定文件,也可以指定目录,指定目录时候必须以反斜杠结尾代表是目录:如下使用方式:

# 使用指定目录
java  -Dspring.profiles.active=test -jar comet-service/target/comet-service-0.1-SNAPSHOT.jar --spring.config.location=/tmp/

# 使用 optional,当目录路径不存在时不报错
java  -Dspring.profiles.active=test -jar comet-service/target/comet-service-0.1-SNAPSHOT.jar --spring.config.location=optional:/tmp/

# 使用指定文件
java  -Dspring.profiles.active=test -jar comet-service/target/comet-service-0.1-SNAPSHOT.jar --spring.config.location=/tmp/application-prod.yaml

# 使用 optional,当文件路径不存在时不报错
java  -Dspring.profiles.active=test -jar comet-service/target/comet-service-0.1-SNAPSHOT.jar --spring.config.location=optional:/tmp/application-prod.yaml
spring.config.additional-location

spring.config.additional-location 配置项和 spring.config.location 的区别在于:

  • 这个属性用于指定除了主配置文件之外的附加配置文件位置。
  • 它允许应用程序加载额外的配置文件,这些文件不会覆盖主配置文件中的设置,而是作为补充。
  • 这可以用于将特定环境的配置与通用配置分开,或者在不重新打包应用程序的情况下动态地添加配置。
  • 与spring.config.location一样,spring.config.additional-location也可以是文件系统路径或类路径下的资源。

例如:

java -jar myapp.jar --spring.config.location=classpath:/default-config.yml --spring.config.additional-location=file:./dev-config.yml

在这个例子中,/default-config.yml是主配置文件,而./dev-config.yml是开发环境的附加配置文件。

容器化场景下最佳实践

现在很多公司都上了 Kubernetes 进行资源管理和容器编排,云原生和容器化部署是大势所趋,最后我带你看下 Spring boot 如何结合 Docker 和 Kubernetes 使用外部配置文件,例子Dockerfile如下:

FROM openjdk

# 定义环境变量,可以dockefile 构建时覆盖
ARG BUILD_ENV=dev
# 定义打包后的 jar 名,注意用 * 号统配版本
ARG JAR_NAME=comet-service-*-SNAPSHOT.jar

# 将 ARG 参数赋值给环境变量
ENV ENV_JAR_NAME=${JAR_NAME}
ENV SPRING_PROFILES_ACTIVE=${BUILD_ENV}

# 添加编译后的jar,到容器内目录
ADD ./comet-service/target/${ENV_JAR_NAME} /opt/
# 注意文件添加到某个目录,目录后需要带 /
ADD ./build/application-test.yaml /opt/config/

# 设置工作目录
WORKDIR /opt/

# 启动命令
ENTRYPOINT java -jar ${ENV_JAR_NAME}

# 端口暴漏
EXPOSE 7878

# 构建
# docker build --progress plain -t comet:v1 -f ./build/Dockerfile .

# 调试
# docker run -it --entrypoint bash -v /tmp/:/tmp  comet:v1

如上一个 dockerfile 构建的镜像,如果想要指定 profile + 读取外置 profile 应该怎么做 ?

很简单,有很多种方法,这里介绍两种最简单的:

(1)构建时添加 外部文件到 jar 的同级目录 /opt/config 下或者 run 的时候动态挂载(更灵活)

(2)在 kubernetes 中挂载文件到 /opt/config 下

然后,如果纯 docker 启动:

# 如果构建时没有添加文件,就挂载目录加指定环境变量
docker run -it -p 7878:7878 -e SPRING_PROFILES_ACTIVE=aone -v /tmp/:/opt/config comet:v1

如果使用 kubernetes 启动:

1,使用 configmap 挂载文件到指定目录
2,注入 env 变量即可

参考文档

Externalized Configuration :: Spring Boot

  • 23
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值