由于@Constraint validatedBy,如何避免层之间的交叉依赖?

在我们的项目中,我们在单独的Maven模块中有Service和DAO层。 服务模块依赖于DAO模块并与其实体一起使用。 问题是我们不能放置自定义jsr 303约束,它使用DAO实体中服务层的一些服务,因为这会创建从DAO层到服务层的后向引用,因为validation器类需要在自定义的validatedBy属性中引用@约束。

有没有办法(使用标准的jsr 303 api)在运行时指定一些自定义约束的validation器类(或以任何其他方式解决我们的问题)? 内置约束具有空validatedBy属性,但我不知道是否有一些api。

您可以使用基于XML的约束映射为您的约束分配validation器,以避免从注释到validation器实现的引用。

BV 1.1 EG也在讨论该领域的一些改进。 您可以在邮件列表中轻松解决问题。

我们在基于Spring的项目中遇到了同样的问题。 为了以最好的Spring方式解决它,我们拆分了ConstraintValidator接口和实现。 例如,在域层中我们只有接口:

public interface UniqueValidator extends ConstraintValidator { } 

在服务层,我们实现了该接口:

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

接下来,我们在Spring Context中为UniqueValidatorJpaImpl声明一个bean。

最后为了让所有工作人员都工作,我们扩展了SpringConstraintValidatorFactory。 默认情况下,它仅创建validatedBy中指定的新类实例。 我们通过首先在spring上下文中查找相应类型的bean来扩展它:

 public class SpringConstraintValidatorFactoryEx implements ConstraintValidatorFactory { private final Logger logger = LoggerFactory.getLogger(SpringConstraintValidatorFactoryEx.class); @Autowired private AutowireCapableBeanFactory beanFactory; public > T getInstance(Class 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; } }