How to avoid cross dependency between layers because of @Constraint validatedBy?

微笑、不失礼 提交于 2019-11-30 18:50:23
Gunnar

You may use an XML based constraint mapping to assign a validator to your constraint to avoid the reference from the annotation to the validator implementation.

The BV 1.1 EG is also discussing some improvements in that area. Feel free to weigh in on the issue on the mailing list.

We faced the same issue in our Spring based project. To solve it in best Spring way we split ConstraintValidator interface and implementation. For example in domain layer we only have interface:

public interface UniqueValidator extends ConstraintValidator<Unique, String> {
}

In service layer we implement that interface:

public class UniqueValidatorJpaImpl implements UniqueValidator {
    private EntityManager entityManager;
    ...
}

Next we declare a bean in Spring Context for UniqueValidatorJpaImpl.

Finally to make all that staff working we extended SpringConstraintValidatorFactory. By default it only creates a new instance of class specified in validatedBy. We extended it by first looking in spring context for a bean of corresponding type:

public class SpringConstraintValidatorFactoryEx implements ConstraintValidatorFactory {

    private final Logger logger = LoggerFactory.getLogger(SpringConstraintValidatorFactoryEx.class);

    @Autowired
    private AutowireCapableBeanFactory beanFactory;

    public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
        T bean = null;

        try {
            logger.info("Trying to find a validator bean of class " + key.getSimpleName());
            bean = this.beanFactory.getBean(key);
        } catch (BeansException exc) {
            logger.info("Failed to find a bean of class " + key.getSimpleName());
        }

        if (bean == null) {
            try {
                logger.info("Creating a new validator bean of class " + key.getSimpleName());
                bean = this.beanFactory.createBean(key);
            } catch (BeansException exc) {
                logger.info("Failed to create a validator of class " + key.getSimpleName());
            }
        }

        if (bean == null) {
            logger.warn("Failed to get validator of class " + key.getSimpleName());
        }

        return bean;
    }

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!