私は完全にSpringを使い始めたばかりで、SOについての質問に対していくつかの回答を調べました。ここにリンクがあります:
Spring 3.1自動配線はカスタム制約バリデーター内では機能しません
Autowiredリポジトリがカスタム制約バリデーターでNull
オブジェクトの検証にHibernate Validatorを使用したいSpringプロジェクトがあります。オンラインで読んだ内容といくつかのフォーラムに基づいて、次のようにバリデーターを挿入しようとしました:
@Bean
public Validator validator() {
return new LocalValidatorFactoryBean().getValidator();
}
しかし、私が使用していたところはどこでも
@Autowired
Validator validator;
Hibernateのバリデーターの代わりに、Springのバリデーター実装を使用していました。 Hibernateバリデーターを正確に挿入する方法がわからなかったため、他のクラスに単純にAutowireするため、安価なトリックを使用しましたが、Java Configは次のようになります
@Bean
public Validator validator() {
// ValidatorImpl is Hibernate's implementation of the Validator
return new ValidatorImpl();
}
(このハッキーな方法でHibernate Validatorを取得しないようにする方法について、誰かが実際に私に正しい方向を示すことができれば私は本当に感謝します)
しかし、ここで主要な問題に行きましょう:
これはカスタム検証定義です
@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;
}
}
上記のカスタム制約バリデーターでは、employeeServiceをnullにしています。 Springの起動時にConstraintValidatorの実装がインスタンス化されないことは知っていますが、ValidatorImpl()を追加すると実際に修正されると思いました。しかし、そうではありませんでした。
今、私は本当にハックな回避策で立ち往生しており、そのようなコードを続行したくありません。誰かが私の状況を助けてくれますか?.
追伸これらは、Java構成ファイル内の私のインポートです。
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;
私は解決策が誰かを助けることを願っています:
@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として提供すると、次のように機能します。
動作方法:HibernateのConstraintValidatorFactory
は、呼び出されない限りConstraintValidators
を初期化しませんが、SpringConstraintValidatorFactory
はAutowireCapableBeanFactory
を指定して初期化します。
[〜#〜]編集[〜#〜]
@shabyasaschiのコメントの1つで述べたように、autowireCapableBeanFactory
を挿入するには、メソッドのシグネチャを次のように変更します。
Validator validator(final AutowireCapableBeanFactory autowireCapableBeanFactory) {
または、次のように設定ファイルにgetterとsetterを追加します。
public AutowireCapableBeanFactory getAutowireCapableBeanFactory() {
return autowireCapableBeanFactory;
}
public void setAutowireCapableBeanFactory(AutowireCapableBeanFactory autowireCapableBeanFactory) {
this.autowireCapableBeanFactory = autowireCapableBeanFactory;
}
これは2つのアプローチで修正できます。
Springを使用してバリデーターにサービスを注入してみてください。
Validatorのinitializeメソッドをオーバーライドして、手動で初期化します。
私は同じ時間前に同じ問題を抱えていましたが、最後に、大量の問題を回避するために2番目のオプションを使用することにしました。
あなたが指摘するように、あなたはあなたのバリデーターで1つの初期化メソッドを定義する必要があり、そこでServiceUtilsを使用して必要なサービスBeanを取得することができます:
@Autowired
private EmployeeService employeeService;
@Override
public void initialize(EmployeeValidation constraintAnnotation) {
//Use an utility service to get Spring beans
employeeService = ServiceUtils.getEmployeeService();
}
また、ServiceUtilsは、静的メソッドで使用される自身への静的参照を持つ通常のSpring Beanです。
@Component
public class ServiceUtils {
private static ServiceUtils instance;
@Autowired
private EmployeeService employeeService;
/* Post constructor */
@PostConstruct
public void fillInstance() {
instance = this;
}
/*static methods */
public static EmployeeService getEmployeeService) {
return instance.employeeService;
}
}
したがって、Springを使用して必要なサービスを注入していますが、通常の方法ではありません。お役に立てれば。
あなたの豆の定義で
@Bean
public Validator validator() {
return new LocalValidatorFactoryBean().getValidator();
}
メソッド定義のValidator
のタイプは何ですか? Springからjavax.validation.Validator
、notValidator
が返されることを確認してください。
Spring bootstrapバリデーターを許可すると、SpringConstraintValidatorFactory
がHibernate Validatorに渡され、制約バリデーター内での依存性注入が可能になります。
それは私のために働いた。現在検索している人のために
public class EmployeeValidator implements ConstraintValidator<EmployeeValidation , Object> {
private EmployeeService employeeService;
public EmployeeValidator(EmployeeService employeeService){
this.employeeService = employeeService;
}
...
}