'Custom @ConfigurationProperties validator

I'm trying to create a custom Validator for a @ConfigurationProperties annotated class. The @Validated annotation has the Class<?>[] value() attribute, on which apparently is where you set the custom validator. I attempted the following with no luck:

public class SomePropertiesValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {
        return SomeProperties.class.isAssignableFrom(clazz);
    }
    
    @Override
    public void validate(Object target, Errors errors) {
        SomeProperties properties = (SomeProperties) target;
    }

}

@Validated(SomePropertiesValidator.class)
@ConfigurationProperties(prefix = "some.prefix")
public class SomeProperties {

    // ...
 
}

None of the SomePropertiesValidator methods are triggered at all. The only way I got it to work, is implementing Validator within the SomeProperties class, but that's not what I'm looking for.

I also tried annotating SomePropertiesValidator with @Component and injecting it manually with the help of the @Bean annotation (also tried it within a static method).



Solution 1:[1]

According to Spring's documentation, the custom validator SomePropertiesValidator needs to be created statically under the name of configurationPropertiesValidator. By doing so, we're creating a global @ConfigurationProperties validator.

"You can also add a custom Spring Validator by creating a bean definition called configurationPropertiesValidator. The @Bean method should be declared static. The configuration properties validator is created very early in the application’s lifecycle, and declaring the @Bean method as static lets the bean be created without having to instantiate the @Configuration class. Doing so avoids any problems that may be caused by early instantiation."

Example:

@Configuration
@EnableConfigurationProperties(SomeProperties.class)
public class SomeConfig {

    @Bean
    public static SomePropertiesValidator configurationPropertiesValidator() {
        return new SomePropertiesValidator();
    }

}

In case you need more than one custom validator, the only way to achieve this is by implementing the Validator interface on your @ConfigurationProperties annotated classes.

Reference: Spring Documentation

Solution 2:[2]

According to The source code doc.

    /**
     * Specify one or more validation groups to apply to the validation step
     * kicked off by this annotation.
     * <p>JSR-303 defines validation groups as custom annotations which an application declares
     * for the sole purpose of using them as type-safe group arguments, as implemented in
     * {@link org.springframework.validation.beanvalidation.SpringValidatorAdapter}.
     * <p>Other {@link org.springframework.validation.SmartValidator} implementations may
     * support class arguments in other ways as well.
     */
    Class<?>[] value() default {};

This parameter is used for validation group.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Henri
Solution 2 Japhy Fan