我创建了一个使用遗留库的Spring Boot应用程序。这个遗留库用XML定义了许多SpringBeans。其中一个将属性值作为构造函数参数:
<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
不使用overriden值,而是使用application.properties
内部的值。
根据Spring Boot文档,命令行中的值应作为第一优先级:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html.这里的情况似乎并非如此,因为如果我从application.properties
中删除该属性,则会使用在命令行上传递的值,因此不会完全忽略命令行值。application.properties
值似乎覆盖了命令行值。
有人知道发生了什么事吗?
使用-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
这个问题的另一个可能原因是您的主方法没有将它接收到的参数传递到它创建的SpringApplication
中。您还应该检查您的主要方法是否类似于以下内容:
public static void main(String[] args) throws Exception {
SpringApplication.run(YourApplication.class, args);
}
注意,args
正被传递到对SpringApplication.run
的调用中。
只是添加了一个典型的错误:应用程序主类中使用的SpringApplication.run
方法接受可变长度的参数,如果不提供参数,则不会引发编译时警告:
public static void main( String[] args )
{
SpringApplication.run( MyApplication.class, args );
}
将args
参数从main方法传递到SpringApplication.run
非常重要。如果不这样做,则不会拾取任何命令行参数或使其生效。
<context:property-placeholder location="classpath:application.properties"/>
从beans.xml文件中删除上面的行(上下文:属性占位符)解决了这个问题。我相信classpath:application.properties正锁定在中的查找位置(防止重写)。
在我的例子中,我在属性占位符上定义了这个:
local-override="true"
所以我删除了这个,它解决了问题。
我最终通过更改为Spring Boot应用程序定义遗留库中bean的方式解决了这个问题。我没有使用定义bean的遗留应用程序的applicationContext.xml,而是在配置类中将它们添加为@Bean
。这解决了问题。