“当前目录”中的 Spring Boot 外部属性文件被忽略

Posted

技术标签:

【中文标题】“当前目录”中的 Spring Boot 外部属性文件被忽略【英文标题】:Spring boot external properties file in "current directory" is ignored 【发布时间】:2017-04-15 02:44:12 【问题描述】:

from the manual:

24.3 应用程序属性文件 SpringApplication 将从以下位置的 application.properties 文件中加载属性并添加 他们到 Spring 环境:

当前目录的 /config 子目录。

当前目录

类路径 /config 包

类路径根

它两次提到当前目录,但这并不意味着什么:

我尝试将它放在我的项目的根目录中(即在与java.io.File( "." ).getCanonicalPath()System.getProperty("user.dir"); 的输出匹配的文件夹中的src 上方),我尝试将它与war 文件一起放入(即在@987654325 中@)

但唯一真正有效的放置位置是默认位置 (src\main\resources)。

那么“当前目录”到底是什么意思?文件真正去哪里了?

我需要为文件找到正确的外部位置,这样我就不必在应用程序中构建数据库凭据。

指南说将application.properties 放在当前目录中会起作用,我找到了将其放入的确切当前目录,但它仍然不起作用,我可以通过以下输出验证:System.out.println(System.getProperty("spring.datasource.url")); 即@ 987654329@ 它仅使用嵌入的属性文件输出正确的值。

【问题讨论】:

故意含糊不清; “当前目录”是“任何目录映射到 '.' 的占位符。立即为您的应用程序”。它可能是启动 tomcat 的当前目录、可执行文件的目录,甚至是根目录,这取决于哪个应用程序是应用服务器,以及它是如何启动的。鉴于以上所有情况,您已经找到了属性文件的最佳位置。如果您不想内置凭据,请设置一个您可以按名称引用的 JNDI 数据源,然后在那里设置凭据。 你知道我发现 getproperty 的输出现在一直为空,即使它正在工作。我很确定我过去看到它不是空的。我真的不知道发生了什么,但我认为它正在获取属性文件,可能是在运行 getproperty 命令之后。 【参考方案1】:

根据ConfigFileApplicationListener:

// Note the order is from least to most specific (last one wins)
private static final String DEFAULT_SEARCH_LOCATIONS =
       "classpath:/,classpath:/config/,file:./,file:./config/";

file:./解析到你启动java进程的工作目录。

【讨论】:

【参考方案2】:

我同意 Stephane Nicoll 的论点,即我们通常不需要将其用于开发和测试,但需要用于属性文件通常外部化且不使用源代码中存在的文件的生产环境。这对我有用,

java -jar myjar.jar --spring.config.location=file:D:\\RunRC\\application.properties

目录 - D:\\RunRC - 上面命令中提到的示例来自我的机器。

我在开发和测试中继续使用源代码的属性文件,即来自\src\main\resources\,但在生产中,我注释掉条目,如果我从D:\\RunRC 开始我的jar 或战争,那么我提供当前目录 如上面的 java 命令所示并将属性文件保留在那里。

只是在做 - @PropertySource( "application.properties")@PropertySource( "file:application.properties") 不会从保存 jar 或 war 的目录中获取它。

对于数据库凭据,我建议使用特定于操作系统的环境变量并使用类似于 - @PropertySource("file:$CONF_DIRdatabase.properties" ) 的语法,其中 CONF_DIR 是指向该目录的现有环境变量。

希望对你有帮助!!

【讨论】:

【参考方案3】:

我了解当前目录是您项目的根目录。但是,您可以使用 -Dspring.config.location=your/config/dir/ 更改此设置。 看看这个帖子enter link description here

【讨论】:

说默认是classpath:,classpath:/config,file:,file:config/【参考方案4】:

如果您搜索“当前目录 java”,您最终会找到 here with this question。目的是如果你把application.properties和应用程序放在同一目录下,它会被默认拾取。

您不会在开发或测试中使用该功能,因为您不应依赖该功能。但是,在生产环境中运行您的应用时,将特定于环境的设置放在应用本身旁边的配置文件中可能会很方便。

【讨论】:

这就是为什么我试图将它放在带有war文件的目录中,我认为这是由bootrun命令启动的。 java -jar your.war 将使用当前目录作为工作目录。 boot run 会将你的主目录放在项目的目录中。而且您不想在那里放置配置文件。同样,不要在开发模式下使用.... 为什么我不能使用主目录?好吧,我能想到一个原因,因为我刚刚尝试过,但没有成功。我还尝试将它与war文件一起使用并运行'java -jar my.war',但它仍然无法正常工作。我让应用程序将配置写入控制台,它们始终显示为“null”,但我知道当我将属性文件内置到 jar 中时,它们不会显示为 null。 工作目录和主目录是两个完全不同的东西。阅读我在答案中提供的链接怎么样? 我将您链接中的代码粘贴到我的应用程序中,并得到以下输出:Current dir:C:\Users\Blade\javaworkspace\AutomationStatisticsPortal Current dir using System:C:\Users\Blade\javaworkspace\AutomationStatisticsPortal 那是我尝试将文件放在首位的地方(即在src 上方) AutomationStatisticsPortal 是父级src 的文件夹。所以我确实尝试了。【参考方案5】:

当前目录是指我们执行 jar 的位置。通过 Spring Boot maven 插件创建可执行 jar 并将 application.properties 放在 jar 文件旁边将起作用。一个例子:here

【讨论】:

以上是关于“当前目录”中的 Spring Boot 外部属性文件被忽略的主要内容,如果未能解决你的问题,请参考以下文章

spring boot 外部配置 - profile 特定配置

Spring Boot 外部化属性不起作用

外部jar中类的spring boot配置属性

Spring Boot WS 应用程序无法加载外部属性

使用 Spring Boot 和 Docker 的外部属性文件

Spring Boot - 添加外部属性文件