Spring Boot命令行属性不覆盖application.properties中定义的属性

时间:2016-05-12 15:57:30

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

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

<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值覆盖了命令行值。

有没有人知道发生了什么?

5 个答案:

答案 0 :(得分:6)

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

您可以使用-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

答案 1 :(得分:1)

<context:property-placeholder location="classpath:application.properties"/>

从我的beans.xml文件中删除上面的行(context:property-placeholder)解决了这个问题。我相信classpath:application.properties正在锁定完全在哪里查看(防止覆盖)。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

就我而言,我在我的财产占位符上定义了这个:

local-override="true"

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

答案 4 :(得分:0)

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

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

args参数从main方法传递到SpringApplication.run很重要。如果您不这样做,那么命令行参数将不会被拾取或生效。