Spring 引导命令行 属性 未覆盖 application.properties 中定义的 属性
Spring Boot command line property not overriding property defined in application.properties
我创建了一个 Spring 启动应用程序,它使用了旧版库。这个遗留库在 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 引导应用程序中,我有一个 application.properties
定义此 属性 如下:
my.url=http://localhost:8080
我在本地使用 Maven Spring 引导插件 运行 我的应用程序如下:
mvn spring-boot:run
并且 属性 值按预期注入到 bean 中。
如果我尝试像这样在命令行上覆盖 my.url
属性:
mvn spring-boot:run -Dmy.url=http://www.override.net
未使用覆盖值,而是使用 application.properties
中的值。
根据 Spring 引导文档,命令行中的值应作为第一优先级选取:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html。这里似乎不是这种情况,因为如果我从 application.properties
中删除 属性 ,那么将使用命令行中传入的值,因此不会完全忽略命令行值. application.properties
值似乎覆盖了命令行值。
有人知道发生了什么事吗?
使用 -D
设置系统 属性。 Spring 引导可以使用系统属性中的配置,所以一般来说,它会起作用。但是,如果 spring-boot:run
为您的应用程序派生一个单独的 JVM,它将无法工作,因为系统 属性 将设置在错误的 JVM 上。由于它不起作用,我想这就是正在发生的事情。
您可以使用 -Drun.arguments
将参数传递给正在 运行 的应用程序,无论它是否是 运行 在派生的 JVM 中。参数应该是一个以逗号分隔的列表,每个列表都以 --
为前缀。例如,设置 my.url
:
mvn spring-boot:run -Drun.arguments=--my.url=http://www.override.net
此问题的另一个可能原因是您的 main 方法没有将它接收到的参数传递到它创建的 SpringApplication
中。您还应该检查您的主要方法是否与此类似:
public static void main(String[] args) throws Exception {
SpringApplication.run(YourApplication.class, args);
}
请注意,args
被传递到对 SpringApplication.run
的调用中。
我最终通过更改为 Spring 启动应用程序定义遗留库中的 bean 的方式解决了这个问题。我没有使用定义 bean 的遗留应用程序的 applicationContext.xml,而是将它们作为 @Bean
添加到我的配置 class 中。这解决了问题。
<context:property-placeholder location="classpath:application.properties"/>
从我的 beans.xml 文件中删除上面的行 (context:属性-placeholder) 解决了这个问题。我相信 classpath:application.properties 正在 确切地 锁定在哪里(防止覆盖)。
在我的例子中,我在 属性-placeholder 上定义了这个:
local-override="true"
所以我删除了它并解决了问题。
只是添加一个典型的错误:应用程序 main class 中使用的 SpringApplication.run
方法接受可变长度参数,如果您不提供任何参数,则不会抛出编译时警告:
public static void main( String[] args )
{
SpringApplication.run( MyApplication.class, args );
}
将 args
参数从 main 方法传递到 SpringApplication.run
很重要。如果不这样做,则不会选取或生效任何命令行参数。
我创建了一个 Spring 启动应用程序,它使用了旧版库。这个遗留库在 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 引导应用程序中,我有一个 application.properties
定义此 属性 如下:
my.url=http://localhost:8080
我在本地使用 Maven Spring 引导插件 运行 我的应用程序如下:
mvn spring-boot:run
并且 属性 值按预期注入到 bean 中。
如果我尝试像这样在命令行上覆盖 my.url
属性:
mvn spring-boot:run -Dmy.url=http://www.override.net
未使用覆盖值,而是使用 application.properties
中的值。
根据 Spring 引导文档,命令行中的值应作为第一优先级选取:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html。这里似乎不是这种情况,因为如果我从 application.properties
中删除 属性 ,那么将使用命令行中传入的值,因此不会完全忽略命令行值. application.properties
值似乎覆盖了命令行值。
有人知道发生了什么事吗?
使用 -D
设置系统 属性。 Spring 引导可以使用系统属性中的配置,所以一般来说,它会起作用。但是,如果 spring-boot:run
为您的应用程序派生一个单独的 JVM,它将无法工作,因为系统 属性 将设置在错误的 JVM 上。由于它不起作用,我想这就是正在发生的事情。
您可以使用 -Drun.arguments
将参数传递给正在 运行 的应用程序,无论它是否是 运行 在派生的 JVM 中。参数应该是一个以逗号分隔的列表,每个列表都以 --
为前缀。例如,设置 my.url
:
mvn spring-boot:run -Drun.arguments=--my.url=http://www.override.net
此问题的另一个可能原因是您的 main 方法没有将它接收到的参数传递到它创建的 SpringApplication
中。您还应该检查您的主要方法是否与此类似:
public static void main(String[] args) throws Exception {
SpringApplication.run(YourApplication.class, args);
}
请注意,args
被传递到对 SpringApplication.run
的调用中。
我最终通过更改为 Spring 启动应用程序定义遗留库中的 bean 的方式解决了这个问题。我没有使用定义 bean 的遗留应用程序的 applicationContext.xml,而是将它们作为 @Bean
添加到我的配置 class 中。这解决了问题。
<context:property-placeholder location="classpath:application.properties"/>
从我的 beans.xml 文件中删除上面的行 (context:属性-placeholder) 解决了这个问题。我相信 classpath:application.properties 正在 确切地 锁定在哪里(防止覆盖)。
在我的例子中,我在 属性-placeholder 上定义了这个:
local-override="true"
所以我删除了它并解决了问题。
只是添加一个典型的错误:应用程序 main class 中使用的 SpringApplication.run
方法接受可变长度参数,如果您不提供任何参数,则不会抛出编译时警告:
public static void main( String[] args )
{
SpringApplication.run( MyApplication.class, args );
}
将 args
参数从 main 方法传递到 SpringApplication.run
很重要。如果不这样做,则不会选取或生效任何命令行参数。