Autowired在Custom Constraint验证器中给出Null值 [英] Autowired gives Null value in Custom Constraint validator

查看:139
本文介绍了Autowired在Custom Constraint验证器中给出Null值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Spring完全不熟悉,因为问题问题,我已经在SO上找了几个答案。以下是链接:

I am totally new to Spring and I have looked in to a few answers on SO for the asked problem. Here are the links:

Spring 3.1自动装配在自定义约束验证器内不起作用

将服务自动装配到验证器中

Autowired Repository在自定义约束验证器中为空

Autowired Repository is Null in Custom Constraint Validator

我有一个Spring项目,我想在其中使用Hibernate Validator进行对象验证。根据我在线阅读的内容以及一些论坛,我尝试按如下方式注入验证器:

I have a Spring project in which I want to use Hibernate Validator for an object validation. Based on what I read online and a few forums I tried to inject validator as follows:

@Bean
  public Validator validator() {
    return new LocalValidatorFactoryBean().getValidator();
  }

但无论我在哪里使用

@Autowired
Validator validator;

这是采用Spring的验证器实现而不是Hibernate的验证器。我无法弄清楚如何准确地注入Hibernate验证器并简单地将其自动装配到其他类中,所以我使用了一个便宜的技巧,现在我的Java Config看起来像这样

It was taking Spring's validator implementation instead of the Hibernate's validator. I couldn't figure out how to exactly inject Hibernate validator and simply Autowire it across other classes so I used a cheap trick, now my Java Config looks like this

@Bean
      public Validator validator() {
        // ValidatorImpl is Hibernate's implementation of the Validator
        return new ValidatorImpl();
      }

我真的很感激,如果有人能指出我进入关于如何避免以这种Hacky方式获取Hibernate Validator的正确方向

但是让我们来看看主要问题:

But lets come to the main issue here:

这是自定义验证定义

@Target( { METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER } )
@Retention(RUNTIME)
@Constraint(validatedBy = EmployeeValidator.class)
@Documented
public @interface EmployeeValidation {
String message() default "{constraints.employeeConstraints}";
public abstract Class<?>[] groups() default {};
public abstract Class<? extends Payload>[] payload() default {};
}

我的自定义验证器

public class EmployeeValidator implements ConstraintValidator<EmployeeValidation , Object> {

@Autowired
private EmployeeService employeeService;

@Override
public void initialize(EmployeeValidation constraintAnnotation) {
//do Something
 }

@Override
public boolean isValid(String type, ConstraintValidatorContext context) {
    return false;
}
}

在上面的Custom Constraint Validator中,我得到employeeService null 。我知道Spring启动时没有实例化ConstraintValidator的任何实现,但我认为添加ValidatorImpl()实际上会解决这个问题。但事实并非如此。

In the above Custom Constraint Validator I get the employeeService null. I know that any implementations of ConstraintValidator are not instantiated when Spring is starting up but I thought adding the ValidatorImpl() will actually fix that. But it didn't.

现在我陷入了一个非常糟糕的解决方法,我不想继续这样的代码。有人可以帮助我解决我的情况。

Now I am stuck with a really hacky workaround and I do not want to continue with a code like that. Can someone please help me with my situation.

P.S。这些是我在Java Config文件中的导入:

P.S. These are my imports in the Java Config file:

import org.hibernate.validator.HibernateValidator; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.MessageSource; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.PropertySource; 
import org.springframework.context.support.ReloadableResourceBundleMessageSource; 
import org.springframework.core.env.Environment; 
import org.springframework.validation.Validator; 
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; 
import org.springframework.web.servlet.LocaleResolver; 
import org.springframework.web.servlet.ViewResolver; 
import org.springframework.web.servlet.config.annotation.EnableWebMvc; 
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; 
import org.springframework.web.servlet.i18n.CookieLocaleResolver; 
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; 
import org.springframework.web.servlet.view.InternalResourceViewResolver; 


推荐答案

我希望解决方案可以帮助某人:

I hope the solution will help someone:

@Bean
public Validator validator () {

    ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
        .configure().constraintValidatorFactory(new SpringConstraintValidatorFactory(autowireCapableBeanFactory))
        .buildValidatorFactory();
    Validator validator = validatorFactory.getValidator();

    return validator;
}

使用SpringConstraintValidatorFactory初始化验证器,以便注入工作并提供验证器实现Hibernate.class以下列方式工作:

Initializing the validator with SpringConstraintValidatorFactory so that injection works and providing the validator implementation to be Hibernate.class works in the following manner:


  1. 您的注册将由您选择的库验证

  2. 您的自定义验证器将能够使用Spring的功能,同时通过Hibernate执行验证。

工作原理:
Hibernate的ConstraintValidtorFactory不会初始化任何ConstraintValidator,除非它们被调用但SpringConstraintValidatorFactory通过向它提供AutowireCapableBeanFactory来实现。

How it works: Hibernate's ConstraintValidtorFactory does not initialize any ConstraintValidators unless they are called but SpringConstraintValidatorFactory does by giving AutowireCapableBeanFactory to it.

编辑
正如@shabyasaschi的评论之一所述要注入autowireCapableBeanFactory,您可以将方法签名更改为:

EDIT As mentioned in one of the comments by @shabyasaschi To inject autowireCapableBeanFactory you can change the method signature as:

Validator validator(final AutowireCapableBeanFactory autowireCapableBeanFactory) {

或在配置文件中为它添加getter和setter,如下所示:

or add getter and setter for it in the config file as follows:

public AutowireCapableBeanFactory getAutowireCapableBeanFactory() {
        return autowireCapableBeanFactory;
}

public void setAutowireCapableBeanFactory(AutowireCapableBeanFactory autowireCapableBeanFactory) {
        this.autowireCapableBeanFactory = autowireCapableBeanFactory;
}

这篇关于Autowired在Custom Constraint验证器中给出Null值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆