Spring 组验证不适用于自动装配的 beans

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

情况

我正在尝试创建一个自动配置,其中某些属性仅在特定情况下必须通过验证。我有一个服务

MyService
,它需要凭证
properties.username
properties.password
,还有一个
OncePerRequestFilter
,它拦截控制器调用并调用
MyService
来执行某些操作,这需要应用程序的名称
properties.app-name

这是全局布局:

  • 当我不提供任何属性并且不存在
    MyService
    bean 时,自动配置不会执行任何操作,
  • 当不存在
    MyService
    bean,但我在属性中提供了用户名和密码时,我将创建一个新的
    MyService
    bean,并且我希望验证用户名和密码,
  • 当存在
    MyService
    bean 时,我将创建一个
    OncePerRequestFilter
    ,并且我希望验证应用程序名称。

为了做到这一点,我想使用验证组。我之前已经在配置属性中实现了一些验证,因此知道 Spring 在实例化对象时检查它们,但我从未尝试过组。

第一次尝试

代码

自动配置

@AutoConfiguration
@EnableConfigurationProperties(MyProperties.class)
public class MyAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "properties", name = { "username", "password" })
    @Validated(CredentialsRequired.class)
    public MyService myDefaultService(@Valid MyProperties properties) {
        return new MyService(properties);
    }

    @Bean
    @ConditionalOnBean(MyService.class)
    @Validated(AppNameRequired.class)
    OncePerRequestFilter myFilter(@Valid MyProperties properties, MyService myService) {
        return new MyFilter(properties, myService);
    }
}

配置属性

@Data
@ConfigurationProperties("properties")
public class MyProperties {
    @NotBlank(groups = AppNameRequired.class)
    private String appName;

    @NotBlank(groups = CredentialsRequired.class)
    private String username;

    @NotBlank(groups = CredentialsRequired.class)
    private String password;
}

结果

当我不提供任何财产时,一切都不会失败,这是我所期望的。但是,如果我只使用以下属性:

properties.username=
properties.password=

然后创建服务和过滤器,而不会出现任何自动验证问题,如这个简短的修改所示:

@Bean
@ConditionalOnBean(MyService.class)
@Validated(AppNameRequired.class)
OncePerRequestFilter myFilter(@Valid MyProperties properties, MyService myService, Validator validator) {
    if(!validator.validate(properties, AppNameRequired.class).isEmpty()) {
        throw new IllegalArgumentException();  // Should not be reached if validation works, but is thrown on instantiation
    }

    return new MyFilter(properties, myService);
}

在属性类上尝试使用
@Validated

我也尝试过在

@Validated
上应用
MyProperties
,但并没有太大改变。此外,我在一个更全球化的案例中注意到了这一点:

  • 当类上有
    @Validated
    且没有组的约束都有效时,即使某些有组的约束无效,也不会抛出错误
  • 当类上存在
    @Validated
    ,但至少违反了一个没有组的约束时,Spring 实例化失败
  • 当类上有
    @Validated(AppNameRequired.class)
    时,没有组的约束都有效,不会抛出错误,即使有组
    AppNameRequired
    的约束无效

我的结论,以及我的问题

综上所述,我的结论是Spring不支持验证组进行bean验证。因此,我想知道:有没有办法仅依靠 Jakarta 和 Spring Boot 注释来执行此条件验证,或者我是否被迫手动调用验证器来执行此操作?

java spring spring-boot spring-bean spring-validator
1个回答
0
投票

您似乎正在尝试使用 Spring MVC 方法,将

@Validated
用于 spring beans。

第一个想法

this文章来看,看起来您需要声明一个额外的bean。

@Bean
    public static MethodValidationPostProcessor validationPostProcessor() {
        return new MethodValidationPostProcessor();
    }

第二个想法

在创建

@ConditionalOnProperty
期间,您可以创建一个
MyService
 bean,而不是依赖于 
@Conditional
,它将验证属性的值。

© www.soinside.com 2019 - 2024. All rights reserved.