提问人:Joe Taylor 提问时间:4/19/2017 更新时间:9/15/2023 访问量:4764
Spring Boot 配置属性的未解析占位符验证
Unresolved Placeholder Validation for Spring Boot Configuration Properties
问:
给定一些具有不可解析占位符的应用程序配置,如下所示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
我检查了简单地将 and 注释应用于类和字段无济于事。@Validated
@Valid
有没有办法保留在绑定的未解析占位符上引发异常的行为?ConfigurationProperties
答:
我在 10 分钟前遇到了同样的问题! 尝试在配置中添加此 bean:
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
propertySourcesPlaceholderConfigurer.setIgnoreUnresolvablePlaceholders(true);
return propertySourcesPlaceholderConfigurer;
}
评论
InitializingBean
afterPropertiesSet()
显然没有更好的解决方案。至少这比 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()
要传入注解的正确正则表达式是@Pattern
^(?!\\$\\{).+
@Validated
@ConfigurationProperties("my.config")
public class ConfigProperties {
@Pattern(regexp = "^(?!\\$\\{).+", message = "unresolved placeholder")
private String uri;
// ...
}
如果您使用的是 on,您可以设置默认值。您可以使用以下命令:@ConfigurationProperties
Props
@Value("#{props.getThing()}")
String theThing;
这也适用于其他 SPeL 上下文,例如Scheduled
@Scheduled(fixedDelayString = "#{@dbConfigurationProperties.getExpirationCheckDelayInMs()}")
void cleanup() {
...
}
评论
@Validated
@NotNull
@NotEmpty
hibernate-validation
@Validation