Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何避免由于@Constraint validatedBy而导致层之间的交叉依赖?_Java_Maven_Bean Validation - Fatal编程技术网

Java 如何避免由于@Constraint validatedBy而导致层之间的交叉依赖?

Java 如何避免由于@Constraint validatedBy而导致层之间的交叉依赖?,java,maven,bean-validation,Java,Maven,Bean Validation,在我们的项目中,在单独的Maven模块中有服务层和DAO层。服务模块依赖于DAO模块并与它的实体一起工作。问题是,我们不能将使用来自服务层的一些服务的自定义jsr 303约束放在DAO实体中,因为这将创建从DAO层到服务层的反向引用,因为需要在custom@constraint的validatedBy属性中引用validator类 有没有一种方法(使用标准JSR303API)在运行时指定某个自定义约束的验证器类(或者以任何其他方式解决我们的问题)?内置约束具有空的validatedBy属性,但我

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

有没有一种方法(使用标准JSR303API)在运行时指定某个自定义约束的验证器类(或者以任何其他方式解决我们的问题)?内置约束具有空的validatedBy属性,但我不知道是否有用于此的api。

您可以使用为约束分配验证器,以避免注释引用验证器实现


这方面也有一些改进。请随时在上讨论这个问题。

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

public interface UniqueValidator extends ConstraintValidator<Unique, String> {
}
public class UniqueValidatorJpaImpl implements UniqueValidator {
    private EntityManager entityManager;
    ...
}
接下来,我们在Spring上下文中为UniqueValidatorJpaImpl声明一个bean

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

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;
    }

}
公共类SpringConstraintValidatorFactoryEx实现ConstraintValidatorFactory{
私有最终记录器Logger=LoggerFactory.getLogger(SpringConstraintValidatorFactoryEx.class);
@自动连线
私人自动布线beanFactory beanFactory;

当使用Hibernate Validator时,您还可以使用服务加载程序机制,避免从约束注释类型到其验证器的任何链接。这里是纯Java EE项目(没有Spring),类似的解决方案将在这里工作。只是稍微简单一点:您只需使用验证方法实现一个接口(无需扩展任何内容),在服务层实现它,并将其直接注入域层的验证器中。这里是纯Java EE项目(无需Spring),类似的解决方案将在这里工作。只是稍微简单一点:您只需使用验证方法实现一个接口(无需扩展任何内容),在服务层实现它,并将其直接注入域层的验证器中。@Aliaksei您能详细说明bean配置吗?我仍然可以使它工作。我添加了一个配置
@bean public UniqueUsernameValidator UniqueUsernameValidator(){return new UniqueUsernameValidator impl();}
@Bean public constraintvalidatorfactor constraintvalidatorfactor(){return new SpringConstraintValidatorFactoryEx();}
但它仍然不起作用,或者我误解了什么。