Spring Cloud Config - 无法解析占位符
Spring Cloud Config - Could not resolve placeholder
背景
我正在尝试向基于 spring 的中型应用程序添加集中配置支持。我最近把它做了 Bootiful :D 它现在可以 运行 作为嵌入式 tomcat 中的 jar,尽管使用与以前相同的旧配置文件。所以接下来我想摆脱文件系统 属性-files。
我有配置服务器设置和工作,由包含配置的 git 存储库支持。
问题
在启动期间,我的应用程序指示在配置服务器上找到 属性 源。
2016-12-15 13:16:19,759 [admin] [ INFO] [] config.client.ConfigServicePropertySourceLocator - Fetching config from server at: http://localhost:8888
2016-12-15 13:16:20,186 [admin] [ INFO] [] config.client.ConfigServicePropertySourceLocator - Located environment: name=myapplication, profiles=[default], label=develop, version=b065758e8ea56ff9f9e8773f263da7705b6aac29
2016-12-15 13:16:20,188 [admin] [ INFO] [] bootstrap.config.PropertySourceBootstrapConfiguration - Located property source: CompositePropertySource [name='configService', propertySources=[MapPropertySource [name='http://configserver@gitserver/config.git/application.properties']]]
问题是映射到用 @Value
注释的字段,例如
@RestController
public class DemoController {
@Value("${my.property}")
private String myProperty;
@RequestMapping("/")
public String myproperty() {
return myProperty;
}
}
堆栈跟踪:
...
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'my.property' in string value "${my.property}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174)
at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126)
...
不会映射 属性,即使对 http://localhost:8888/myapplication/default
的请求响应为:
{
"name": "myapplication",
"profiles": [
"default"
],
"label": "develop",
"version": "b065758e8ea56ff9f9e8773f263da7705b6aac29",
"state": null,
"propertySources": [
{
"name": "http://configserver@gitserver/config.git/application.properties",
"source": {
"my.property": "Test successful"
}
}
]
}
我试过的
一尘不染
如果我转到 https://start.spring.io/ 并使用云配置客户端 dep 生成一个项目并将其设置为获取与我的其他项目相同的属性,一切都会按预期进行。这让我认为我的更大项目中存在一些依赖性,这与属性的解析方式相冲突。如果我在启动期间调试项目,我可以看到我的配置服务器的属性在 spring Environment
中,但不会在 PropertyPlaceholder 中结束。
配置属性
将属性从配置服务器映射到用 @ConfigurationProperties
注释的 POJO 可以解决这个问题。但是我无法控制所有 @Value
注释 类 所以我不能将这种方法用于其他团队的库。
...所以
有没有什么方法可以确保 在 @Value
注释被解析之前映射云配置属性?
解决方案是(如 M.Deinum 指出的那样)删除一个较旧的 xml 配置文件中定义的 <context:property-placeholder />
。在我的例子中,它是从另一个导入的 xml 配置文件导入的。一旦我用 java 配置替换了 "another.xml" 的导入,问题就解决了。
谢谢@M.Deinum!
AdminConfig.java:
@Configuration
@ImportResource(value = {
"classpath:/legacy-conf/applicationContext.xml"
})
public class AdminConfig {
//... Bean definitions
}
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">
...other config...
<import resource="classpath:another.xml"/>
</beans>
another.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
...other config...
<context:property-placeholder />
</beans>
背景
我正在尝试向基于 spring 的中型应用程序添加集中配置支持。我最近把它做了 Bootiful :D 它现在可以 运行 作为嵌入式 tomcat 中的 jar,尽管使用与以前相同的旧配置文件。所以接下来我想摆脱文件系统 属性-files。 我有配置服务器设置和工作,由包含配置的 git 存储库支持。
问题
在启动期间,我的应用程序指示在配置服务器上找到 属性 源。
2016-12-15 13:16:19,759 [admin] [ INFO] [] config.client.ConfigServicePropertySourceLocator - Fetching config from server at: http://localhost:8888
2016-12-15 13:16:20,186 [admin] [ INFO] [] config.client.ConfigServicePropertySourceLocator - Located environment: name=myapplication, profiles=[default], label=develop, version=b065758e8ea56ff9f9e8773f263da7705b6aac29
2016-12-15 13:16:20,188 [admin] [ INFO] [] bootstrap.config.PropertySourceBootstrapConfiguration - Located property source: CompositePropertySource [name='configService', propertySources=[MapPropertySource [name='http://configserver@gitserver/config.git/application.properties']]]
问题是映射到用 @Value
注释的字段,例如
@RestController
public class DemoController {
@Value("${my.property}")
private String myProperty;
@RequestMapping("/")
public String myproperty() {
return myProperty;
}
}
堆栈跟踪:
...
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'my.property' in string value "${my.property}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174)
at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126)
...
不会映射 属性,即使对 http://localhost:8888/myapplication/default
的请求响应为:
{
"name": "myapplication",
"profiles": [
"default"
],
"label": "develop",
"version": "b065758e8ea56ff9f9e8773f263da7705b6aac29",
"state": null,
"propertySources": [
{
"name": "http://configserver@gitserver/config.git/application.properties",
"source": {
"my.property": "Test successful"
}
}
]
}
我试过的
一尘不染
如果我转到 https://start.spring.io/ 并使用云配置客户端 dep 生成一个项目并将其设置为获取与我的其他项目相同的属性,一切都会按预期进行。这让我认为我的更大项目中存在一些依赖性,这与属性的解析方式相冲突。如果我在启动期间调试项目,我可以看到我的配置服务器的属性在 spring Environment
中,但不会在 PropertyPlaceholder 中结束。
配置属性
将属性从配置服务器映射到用 @ConfigurationProperties
注释的 POJO 可以解决这个问题。但是我无法控制所有 @Value
注释 类 所以我不能将这种方法用于其他团队的库。
...所以
有没有什么方法可以确保 在 @Value
注释被解析之前映射云配置属性?
解决方案是(如 M.Deinum 指出的那样)删除一个较旧的 xml 配置文件中定义的 <context:property-placeholder />
。在我的例子中,它是从另一个导入的 xml 配置文件导入的。一旦我用 java 配置替换了 "another.xml" 的导入,问题就解决了。
谢谢@M.Deinum!
AdminConfig.java:
@Configuration
@ImportResource(value = {
"classpath:/legacy-conf/applicationContext.xml"
})
public class AdminConfig {
//... Bean definitions
}
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">
...other config...
<import resource="classpath:another.xml"/>
</beans>
another.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
...other config...
<context:property-placeholder />
</beans>