Spring 引导和休眠验证的 ConstraintMappingContributor

Spring Boot & Hibernate Validation's ConstraintMappingContributor

hibernate 验证文档描述了如何创建 ConstraintMappingContributors here

它指出:

You then need to specify the fully-qualified class name of the contributor implementation in META-INF/validation.xml, using the property key hibernate.validator.constraint_mapping_contributors. You can specify several contributors by separating them with a comma.

鉴于我有很多这样的东西,什么是最合适的自动发现它们的方法,即通过@Component 并在运行时动态地将它们添加到[=期间的ConstrainMappingConfiguration 23=] 开机启动。

例如.. 如果开发人员创建了一个新的 ConstraintMappingContributor,它应该会在 spring 启动时自动获取并添加,不需要更改其他文件。

这是我想出的,似乎对我有用。

package...
import org.hibernate.validator.spi.cfg.ConstraintMappingContributor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Configuration
public class ValidationConfiguration {

    private final List<ConstraintMappingContributor> contributors;
    public ValidationConfiguration(Optional<List<ConstraintMappingContributor>> contributors) {
        this.contributors = contributors.orElseGet(ArrayList::new);
    }

    @Bean
    public LocalValidatorFactoryBean validatorFactory() {
        return new ValidatorFactoryBean(this.contributors);
    }
}



package...
import org.hibernate.validator.HibernateValidatorConfiguration;
import org.hibernate.validator.internal.cfg.context.DefaultConstraintMapping;
import org.hibernate.validator.spi.cfg.ConstraintMappingContributor;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

import javax.validation.Configuration;
import java.util.List;

public class ValidatorFactoryBean extends LocalValidatorFactoryBean {

    private final List<ConstraintMappingContributor> contributors;

    ValidatorFactoryBean(List<ConstraintMappingContributor> contributors) {
        this.contributors = contributors;
    }

    @Override
    protected void postProcessConfiguration(Configuration<?> cfg) {
        if (cfg instanceof HibernateValidatorConfiguration) {
            HibernateValidatorConfiguration configuration = (HibernateValidatorConfiguration) cfg;
            this.contributors.forEach(contributor -> contributor.createConstraintMappings(() -> {
                DefaultConstraintMapping mapping = new DefaultConstraintMapping();
                configuration.addMapping(mapping);
                return mapping;
            }));
        }
    }
}

我这样调用它...

if(SpringValidatorAdapter.class.isInstance(this.validatorFactory)){
    SpringValidatorAdapter.class.cast(this.validatorFactory).validate(entity, errors);
}