向 Spring v5 (Spring Boot v2) 中的
ClockProvider
配置提供您自己的 ValidatorFactory
的正确方法是什么,以便在注入 Bean Validations Validator
的任何地方使用它?
用例:您希望为其认为“当前”的内容提供一个缓冲区,如本博客文章中所述,以考虑合理的时钟漂移量。
最简单的解决方案,也保持所有 Spring 默认值不变,是重写方法
postProcessConfiguration()
:
@Configuration
class TimeConfiguration {
@Bean
static Clock clock() {
return Clock.fixed(
Instant.ofEpochSecond(1700000000), ZoneOffset.UTC
);
}
@Bean
static LocalValidatorFactoryBean defaultValidator(Clock clock) {
LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean() {
@Override
public void postProcessConfiguration(
jakarta.validation.Configuration<?> configuration) {
configuration.clockProvider(() -> clock);
}
};
MessageInterpolatorFactory interpolatorFactory =
new MessageInterpolatorFactory();
factoryBean.setMessageInterpolator(interpolatorFactory.getObject());
return factoryBean;
}
}
Spring 5 仅在运行时与 Bean Validation 2.0 兼容,后者引入了您想要使用的 ClockProvider。请参阅 Spring sources 中的下一个代码。我认为有两种方法可以解决这个问题。您可以尝试使用验证器的 xml 配置并在那里指定时钟提供程序。它在你的validation.xml中看起来像这样:
<validation-config
xmlns="http://xmlns.jcp.org/xml/ns/validation/configuration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/validation/configuration
http://xmlns.jcp.org/xml/ns/validation/configuration/validation-configuration-2.0.xsd"
version="2.0">
// any other configurations...
<clock-provider>com.acme.ClockProvider</clock-provider>
</validation-config>
如果您不喜欢 xml,另一种选择是尝试定义并使用您自己的
LocalValidatorFactoryBean
。
另请注意,对于您的用例来说,使用 Hibernate Validator 中引入的相对较新的功能(时间验证容差)可能会很有用,它允许指定时间约束的容差。有关它的更多详细信息,请参阅文档。此容差也可以在 xml 中以及以编程方式设置。
检查这个博客文章
@Bean
@ConditionalOnMissingBean(ClockProvider.class) // to allow tests to overwrite it
public ClockProvider getClockProvider() {
return () -> Clock.systemDefaultZone();
}