如何在使用命令行 Gradle (6.4) 构建 Spring Boot 应用程序时传递 spring.config.location="some path"
Posted
技术标签:
【中文标题】如何在使用命令行 Gradle (6.4) 构建 Spring Boot 应用程序时传递 spring.config.location="some path"【英文标题】:How to pass spring.config.location="somepath" while building SpringBoot application with command-line Gradle (6.4) build 【发布时间】:2020-10-15 22:38:48 【问题描述】:我有一个 SpringBoot 应用程序,其中我在项目之外有 application.properties 文件(它不在通常的位置 src/main/resources 中)。
使用gradle clean build
构建应用程序时,由于代码无法找到属性文件而失败。
我尝试了许多命令来传递 vm args、gradle opts 但它不起作用。
gradle clean build -Djvmargs="-Dspring.config.location=/users/home/dev/application.properties" //not working
当它创建 Spring 应用程序上下文并且无法替换属性占位符时,它在测试阶段失败。如果我以gradle clean build -x test
跳过测试,它可以工作。
虽然我可以使用java -jar api.jar --spring.config.location=file:/users/home/dev/application.properties
运行应用程序
请帮助我如何使用命令行在 gradle 构建中传递 spring.config.location=/users/home/dev/application.properties
,以便构建与所有 Junit 测试一起运行
【问题讨论】:
【参考方案1】:如果我是你,我不会参与 junit 测试的实际属性。所以我会在src/test/resources/application-test.properties
下为项目创建一个测试属性,并在junit test 中加载测试属性。
示例:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyProperties.class)
@TestPropertySource("classpath:application-test.properties")
public class MyTestExample
@Test
public void myTest() throws Exception
...
【讨论】:
我不能在项目中拥有属性文件。它是一个包含应用程序属性文件的单独存储库。也有不同的属性文件进行测试会重复它。 你可以在你的项目中尝试以下命令gradle clean build -Dspring.config.location=/users/home/dev/application.properties
也许这篇文章会帮助你在外部传递 application.property ***.com/a/52099774/13167832
我已经尝试过了。这是行不通的。我需要 args 来“构建”而不是“bootRun”。
如果没有任何效果,我猜,我必须按照@nikob-bob 的建议为 Junit 测试创建不同的配置文件【参考方案2】:
运行 Gradle 的系统属性不会自动传递给测试框架。我认为这是为了尽可能地隔离测试,因此环境的差异不会导致结果的差异,除非以这种方式明确配置。
如果查看Test task 的Gradle API,可以看到可以通过任务上的systemProperty
方法(Groovy DSL)配置系统属性:
test
systemProperty "spring.config.location", "/path/to/my/configuration/repository/application.properties"
如果您还想从 Gradle 命令行读取系统属性然后通过该测试,则必须先从 Gradle 读取它,例如作为项目属性,然后将该值传递给测试:
test
if (project.hasProperty('testconfig'))
systemProperty 'spring.config.location', project.getProperty('testconfig')
使用gradle -Ptestconfig="/path/to/my/configuration/repository/application.properties" build
运行它
但是,如果可以避免的话,我不鼓励在构建命令行上使用系统属性。至少,从长远来看,它会让你非常恼火。如果配置文件可以位于不同机器上的不同位置(取决于您签出存储库的位置以及它与 Spring Boot 存储库的相对路径不同),您可能需要在个人 @987654326 中指定它@ 文件。
【讨论】:
很好的解决方案,它奏效了。正是我想要的。谢谢比约恩·维斯特。【参考方案3】:我觉得有误会。
spring.config.location 在运行时使用
正如您所验证的:
java -jar api.jar --spring.config.location=file:/users/home/dev/application.properties
spring.config.location 在运行时使用或需要,不是在构建时。
在构建您的 Spring Boot 应用程序时,需要一个 application.properties。一种方法可以是使用带有模板值的 src/main/resources/application.properties,但在运行时您将忽略它spring.config.location=file...
用于单元测试
在这种情况下,正如@nikos-bob 所说,您必须使用其他属性,通常在您的src/test/resources
中
环境变量代替外部属性
我们不想在我们的主 git 存储库 src/main/resources/application.properties 中有硬编码的值,所以第一个想法是使用外部属性。但是这个文件必须存放在另一个git仓库(相当于主仓库)或者手动创建。
Spring 和其他框架为我们提供了另一种选择:使用环境变量。
因此,与其手动外部创建 application.properties 或将其存储在我们的 git 存储库中,您的 Spring Boot 应用程序始终必须具有 application.properties 但带有环境变量:
spring.datasource.url=jdbc:oracle:thin:@$DATABASE_HOST:$DATABASE_PORT:$DATABASE_SID
spring.datasource.username=$DATABASE_USER
spring.datasource.password=$DATABASE_PASSWORD
spring.mail.host = $MAIL_HOST
spring.mail.username =$MAIL_USERNAME
spring.mail.password =$MAIL_PASSWORD
优点:
无需手动创建 application.properties,让我们能够更轻松地实现 devops 自动化 不需要spring.config.location=file..【讨论】:
感谢您的意见。在构建时未使用 application.properties 时,如果我将 application.properties 文件放入 src/main/resources,则 gradle clean build 有效。但是如果在资源文件夹中没有它,那么 gradle clean build 会失败。这意味着在构建时它需要 application.properties 文件。这实际上就是我们编写测试用例的方式。正如我在测试阶段所说,它会启动应用程序。但问题是如何指定外部配置文件以便 gradle clean build 工作。可能是我们无法在构建时指定 spring.config.location=file ,这是我正在弄清楚的。 具有虚拟值(如password = changeme
)的属性如何用于构建。对于您的测试问题,如果您在 github 中编写了一个最小存储库,也许我可以尝试重现。你在窗户里吗?
正如你和@nikos-bob 提到的,如果我为测试创建一个不同的道具文件,并在测试中使用它,那么构建工作正常。我已经测试过了。所以看来我可以采用这种方法。但是,如果我可以在命令行中指定 Gradle 构建的配置文件的路径,或者在 build.gradle 文件中说,那将是完美的。我的代码在公司托管的 git repo 中。以上是关于如何在使用命令行 Gradle (6.4) 构建 Spring Boot 应用程序时传递 spring.config.location="some path"的主要内容,如果未能解决你的问题,请参考以下文章
如何在针对特定 Gradle 构建风格的同时从命令行运行单个单元测试方法
使用 android studio 项目在命令行上使用 Gradle 构建失败:Xlint 错误