Spring Boot 配置属性未解决的占位符验证

问题描述 投票:0回答:4

给定一些带有无法解析占位符的应用程序配置,如下所示

application.yml

my:
  thing: ${missing-placeholder}/whatever

当我使用

@Value
注释时,配置文件中的占位符会被验证,所以在这种情况下:

package com.test;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class PropValues {
    @Value("${my.thing}") String thing;
    public String getThing() { return thing; }
}

我得到一个

IllegalArgumentException: Could not resolve placeholder 'missing-placeholder' in value "${missing-placeholder}/whatever"
。这是因为该值是由
AbstractBeanFactory.resolveEmbeddedValue
直接设置的,并且没有任何东西可以捕获
PropertyPlaceholderHelper.parseStringValue

抛出的异常

但是,希望转向

@ConfigurationProperties
风格,我注意到缺少此验证,例如在本例中:

package com.test;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

@ConfigurationProperties(prefix = "my")
public class Props {
    private String thing;
    public String getThing() { return thing; }    
    public void setThing(String thing) { this.thing = thing; }
}

无一例外。我可以看到

PropertySourcesPropertyValues.getEnumerableProperty
使用注释
// Probably could not resolve placeholders, ignore it here
捕获异常并将无效值收集到其内部映射中。后续数据绑定不会检查未解析的占位符。

我检查了简单地将

@Validated
@Valid
注释应用于类和字段没有帮助。

有什么方法可以保留使用

ConfigurationProperties
绑定在未解析的占位符上抛出异常的行为吗?

spring validation spring-boot configuration spring-boot-configuration
4个回答
0
投票

显然没有更好的解决方案。至少这比 afterPropertiesSet() 好一些。

@Data
@Validated // enables javax.validation JSR-303
@ConfigurationProperties("my.config")
public static class ConfigProperties {
    // with @ConfigurationProperties (differently than @Value) there is no exception if a placeholder is NOT RESOLVED. So manual validation is required!
    @Pattern(regexp = ".*\$\{.*", message = "unresolved placeholder")
    private String uri;
    // ...
}

更新:我第一次得到了正则表达式错误。它匹配整个输入(不仅仅是

java.util.regex.Matcher#find()
)。


0
投票

传入

@Pattern
注释的正确正则表达式是
^(?!\\$\\{).+

@Validated
@ConfigurationProperties("my.config")
public class ConfigProperties {
    
    @Pattern(regexp = "^(?!\\$\\{).+", message = "unresolved placeholder")
    private String uri;
    // ...
}

0
投票

如果您在

@ConfigurationProperties
上使用
Props
,您可以在其中设置默认值。您可以使用以下内容:

@Value("#{props.getThing()}")
String theThing;

这也适用于其他 SPeL 环境,例如

Scheduled

@Scheduled(fixedDelayString = "#{@dbConfigurationProperties.getExpirationCheckDelayInMs()}")
void cleanup() {
...
}

-1
投票

10 分钟前我也遇到了同样的问题! 尝试在您的配置中添加此 bean:

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
        propertySourcesPlaceholderConfigurer.setIgnoreUnresolvablePlaceholders(true);
        return propertySourcesPlaceholderConfigurer;
    }
© www.soinside.com 2019 - 2024. All rights reserved.