常见的 spring boot 应用多是打包成 jar 包运行在服务器,这包含了一系列的配置文件以及第三方的依赖,不过这也引发了常见的思考:除application.properties
之外的其它配置文件变动,是否需要重新打包再重新部署?如日志配置文件、mybatis 的 xml 文件。
先来看看 Spring Boot 是如何加载核心配置文件的,在org.springframework.boot.context.config.ConfigFileApplicationListener
的内部类Loader
的load()
可以查看具体实现,以下优先级从高到低依次为:
通过启动命令指定:
java -jar -Dspring.config.location=xxx/application.properties demo.jar
Jar 包同级目录下的
config
目录Jar 包同级目录
classpath (
resources
) 同级目录下的config
目录classpath (
resources
) 目录
留意到这段代码定义:
// 默认的搜索路径,对应了上面描述的优先级
private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/";
而 classpath 路径是可以指定的,在Application
启动类添加如下代码,来看看默认的 jar 应用程序对应的 resources 位置:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
System.out.println(DemoApplication.class.getResource("/"));
}
}
相应的输出结果为:jar:file:/C:/xxx/demo.jar!/BOOT-INF/classes!/
因为java -jar
所指定及对应的优先级是最高的,所以启动时设定 classpath 就可以达到想要的效果:将配置文件从 Jar 包独立出来进行管理。
以下是该对应扩展方式的几种说明:
-
-Xbootclasspath:
完全替换基本的 Java class 搜索路径(不常用) -
-Xbootclasspath/p:
将 classpath 添加在核心class搜索路径前面(不常用,避免引起冲突) -
-Xbootclasspath/a:
将classpath添加在核心class搜索路径后面 (常用)
最后,这里通过指定当前目录下的resources
文件夹进行了简单测试:java -jar -Xbootclasspath/a:./resources/ demo.jar
,观察启动日志是否可以读取 logback 配置:
相应的输出及日志为:file:/C:/xxx/demo-project/target/resources/
,结果符合预期。
参考链接
文章已授权转载,原文链接:如何在 Jar 包外管理 Spring Boot 应用的配置文件