解决springboot外部配置文件spring.config.location不生效的问题

解决springboot外部配置文件spring.config.location不生效的问题

一、背景

原文链接 springboot 如何引用外部配置文件(spring.config.location)-CSDN博客 仅作分享,感谢作者
本文写的是单应用下的springboot,并非微服务,如果是微服务可以参考nocos或者springcloud config。

一般在企业开发流水线中,都会涉及到几个环境的发布,dev开发环境,test测试环境,prod生产环境等等,那么如果需要发布一个项目到不同的环境会有几种方式:(个人拙见)

第一,可以通过maven打包的方式指定特定环境的配置,这种方式就需要在打包的时候对环境做出区分,对于一些企业可能打包的工具是不区分环境的。
第二,也可以通过springboot运行时指定配置文件的环境,这样的话配置文件可能需要被管理在项目中,那么无法很好保护生产环境的配置。
第三,也可以通过环境变量的方式,区分不同环境的配置,这种方式缺点是要维护一份环境变量的文件,没有配置文件来的简便,不过也是一种方式。
最后就是就特定环境的配置放在服务器特定目录下,通过项目引用外部的配置文件来区分环境。
现在就按第四种展开。先了解springboot的默认加载方式。

二、springboot 默认的配置文件加载顺序

24.3 Application property files
SpringApplication will load properties from application.properties files in the following locations and add them to the Spring Environment:

A /config subdirectory of the current directory.
The current directory
A classpath /config package
The classpath root
The list is ordered by precedence (properties defined in locations higher in the list override those defined in lower locations).

这里说了四种方式可以把配置文件放到外部的。

第一种是在jar包的同一目录下建一个config文件夹,然后把配置文件放到这个文件夹下;
第二种是直接把配置文件放到jar包的同级目录;
第三种在classpath下建一个config文件夹,然后把配置文件放进去;
第四种是在classpath下直接放配置文件。
这里的优先级也是依次降低,优先级高的覆盖优先级低的,可以注意点的是,只是对相同配置项才会产生覆盖作用,不同的话是互补作用,也就是说如果四个地方都配了的话,是会累加起来的。
另外,如果我们需要自定义配置文件路径的话,可以通过命令行启动程序时配置 --spring.config.location=xxx.properties就可以达到目的,但是对运维就不太优化,因为在启动命令时候要配置好这个特定项目路径。那么如果通过一个配置项spring.config.location来实现配置。

三、spring.config.location为什么没有生效

原因是在application配置文件里面指定spring.config.location的优先级太低了,加载太迟了,导致加载不到特定的配置文件,因此在通过命令行启动的方式可以提高优先级,加载到配置文件。

四、通过spring.cloud的方式

spring cloud中 通过bootstrap.yml/properties来加载配置中心的配置。那么bootstrap/ application 的区别?

Spring Cloud 构建于 Spring Boot 之上,在 Spring Boot 中有两种上下文,一种是 bootstrap, 另外一种是 application, bootstrap 是应用程序的父上下文,也就是说 bootstrap 加载优先于 applicaton。bootstrap 主要用于从额外的资源来加载配置信息,还可以在本地外部配置文件中解密属性。这两个上下文共用一个环境,它是任何Spring应用程序的外部属性的来源。bootstrap 里面的属性会优先加载,它们默认也不能被本地相同配置覆盖

因此,对比 application 配置文件,bootstrap 配置文件具有以下几个特性。

boostrap 由父 ApplicationContext 加载,比 applicaton 优先加载
boostrap 里面的属性不能被覆盖
好了 最后通过引用组件:Spring Cloud Context,bootstrap文件才能生效。

<!--需要引入该jar才能使bootstrap配置文件生效--> 
<dependency> 
    <groupId>org.springframework.cloud</groupId> 
    <artifactId>spring-cloud-context</artifactId> 
</dependency>

原文:springboot 外部配置文件spring.config.location 为什么不生效? - 1994的地铁 - 博客园
作者:1994的地铁