Spring Cloud Config - 无法解析占位符

时间:2016-12-15 13:08:56

标签: spring spring-boot spring-cloud spring-cloud-config

背景

我正在尝试为中型弹簧应用程序添加集中配置支持。我最近做了它Bootiful:D它现在可以作为一个jar在嵌入式tomcat中运行,尽管使用与以前相同的旧配置文件。接下来我想摆脱文件系统属性文件。 我有Config服务器设置和工作,由包含配置的git repo支持。

问题

在启动期间,我的应用程序表明在配置服务器上找到了属性源。

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

将属性从配置服务器映射到使用@ConfigurationProperties注释的POJO可以解决问题。但我不能控制所有@Value注释类,所以我不能将这种方法用于其他团队的库。

...所以

在解析 @Value注释之前,是否有某种方法可以确保cloud-config属性已映射

1 个答案:

答案 0 :(得分:2)

解决方案是(正如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>