【问题标题】:Spring Boot command line property not overriding property defined in application.propertiesSpring Boot 命令行属性不覆盖 application.properties 中定义的属性
【发布时间】:2016-05-12 15:57:30
【问题描述】:

我创建了一个使用旧库的 Spring Boot 应用程序。这个遗留库在 XML 中定义了许多 Spring Bean。其中之一将属性值作为构造函数参数:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="myBean" class="com.em.MyBean">
        <constructor-arg name="url" value="${my.url}"/>
    </bean>
</beans>

在我的 Spring Boot 应用程序中,我有一个 application.properties,它定义这个属性如下:

my.url=http://localhost:8080

我使用 Maven Spring Boot 插件在本地运行我的应用程序,如下所示:

mvn spring-boot:run

并且按预期将属性值注入到bean中。

如果我尝试像这样覆盖命令行上的my.url 属性:

mvn spring-boot:run -Dmy.url=http://www.override.net

不使用覆盖的值,而是使用application.properties 中的值。

根据 Spring Boot 文档,命令行中的值应作为第一优先级:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html。这似乎不是这种情况,因为如果我从application.properties 中删除该属性,则使用在命令行中传入的值,因此不会完全忽略命令行值。 application.properties 的值似乎覆盖了命令行值。

有人对发生的事情有任何想法吗?

【问题讨论】:

  • 我认为使用 -D 会将属性作为 jvm 参数而不是 spring boot 属性传递。你试过使用--my.url=http://www.override.net吗?
  • 您能发布您的完整版本的 XML 配置吗?
  • @RahulSharma 我已经按照下面安迪的建议进行了尝试,没有任何区别。
  • @AliDehghani。你的意思是 XML bean 配置?如果是这样,那里没有任何争议,但我已经编辑了问题以包含完整的配置。
  • 只是好奇,你有没有试过只做--my.url=http://www.override.net 而没有任何-Drun.arguments=..?所以只是mvn spring-boot:run --my.url=http://www.override.net。那它有什么作用吗?

标签: java spring spring-boot spring-boot-maven-plugin spring-properties


【解决方案1】:

使用-D 设置系统属性。 Spring Boot 可以使用系统属性中的配置,所以一般来说,它会起作用。但是,如果spring-boot:run 为您的应用程序分叉一个单独的 JVM,它将不起作用,因为 System 属性将设置在错误的 JVM 上。由于它不起作用,我猜这就是正在发生的事情。

您可以使用-Drun.arguments 将参数传递给正在运行的应用程序,无论它是否在分叉的JVM 中运行。参数应该是一个逗号分隔的列表,每个列表都以-- 为前缀。比如设置my.url:

mvn spring-boot:run -Drun.arguments=--my.url=http://www.override.net

此问题的另一个可能原因是您的 main 方法没有将它接收到的参数传递到它创建的 SpringApplication 中。您还应该检查您的 main 方法是否类似于:

public static void main(String[] args) throws Exception {
    SpringApplication.run(YourApplication.class, args);
}

请注意,args 被传递到对 SpringApplication.run 的调用中。

【讨论】:

  • 我已经尝试更改传递参数的方式(即使用 -Drun.arguments.... 并且没有区别。主要方法已经通过参数到创建的应用程序中。我在application.properties文件中有许多其他属性,我能够使用-Dproperty.name = value在命令行上成功覆盖它们。看起来这与事实有关这个特定的属性用于我所依赖的库中定义的 Spring bean。
【解决方案2】:
<context:property-placeholder location="classpath:application.properties"/>

从我的 beans.xml 文件中删除上面的行 (context:property-placeholder) 解决了这个问题。我相信 classpath:application.properties 锁定在 确切 的位置(防止覆盖)。

【讨论】:

  • 我的应用程序 YAML 文件中的属性没有被读取,我也遇到了类似的问题,删除 context:property-placeholder 元素也解决了我的问题。不错的收获。
【解决方案3】:

就我而言,我在属性占位符上定义了这个:

local-override="true"

所以我删除了它,它解决了问题。

【讨论】:

    【解决方案4】:

    只是添加一个典型错误:应用程序主类中使用的SpringApplication.run 方法接受可变长度参数,如果不提供任何参数,则不会引发编译时警告:

    public static void main( String[] args )
    {
        SpringApplication.run( MyApplication.class, args );
    }
    

    args 参数从 main 方法传递给 SpringApplication.run 很重要。如果您不这样做,则不会拾取或生效任何命令行参数。

    【讨论】:

      【解决方案5】:

      我最终通过更改为 Spring Boot 应用程序定义遗留库中的 bean 的方式解决了这个问题。我没有使用定义 bean 的遗留应用程序的 applicationContext.xml,而是将它们作为 @Beans 添加到我的配置类中。这解决了问题。

      【讨论】:

        猜你喜欢
        • 2020-06-22
        • 1970-01-01
        • 1970-01-01
        • 2018-04-12
        • 1970-01-01
        • 2017-01-24
        • 2020-05-03
        • 2017-09-19
        • 2019-03-20
        相关资源
        最近更新 更多