Vip*_*pul 3 java validation dependency-injection guice
我有一个在 ConstraintValidator 的实现中注入类的用例。我正在使用 Google guice 进行依赖项注入,目前无法在验证器内注入。
我的场景的简化形式
内部模块:
@Provides
@Singleton
public ServiceA getServiceA() {
return new ServiceA();
}
Run Code Online (Sandbox Code Playgroud)
约束验证器:
public class MyValidator implements ConstraintValidator<ValidS,List<String>> {
private final ServiceA serviceA;
@Inject
public MyValidator(ServiceA serviceA) {
this.serviceA = serviceA;
}
@Override
public void initialize(final ValidS validS) {
}
@Override
public boolean isValid(final List<String> sList, final ConstraintValidatorContext constraintValidatorContext) {
System.out.println(serviceA.testInjection());
//validation code
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:添加异常消息:
HV000064: Unable to instantiate ConstraintValidator: class com.validation.MyValidator.
javax.validation.ValidationException: HV000064: Unable to instantiate ConstraintValidator: class com.validation.MyValidator.
at org.hibernate.validator.internal.util.privilegedactions.NewInstance.run(NewInstance.java:51) ~[hibernate-validator-5.0.1.Final.jar:5.0.1.Final]
at org.hibernate.validator.internal.util.ReflectionHelper.run(ReflectionHelper.java:671) ~[hibernate-validator-5.0.1.Final.jar:5.0.1.Final]
at org.hibernate.validator.internal.util.ReflectionHelper.newInstance(ReflectionHelper.java:219) ~[hibernate-validator-5.0.1.Final.jar:5.0.1.Final]
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorFactoryImpl.getInstance(ConstraintValidatorFactoryImpl.java:34) ~[hibernate-validator-5.0.1.Final.jar:5.0.1.Final]
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager.createAndInitializeValidator(ConstraintValidatorManager.java:141) ~[hibernate-validator-5.0.1.Final.jar:5.0.1.Final]
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager.getInitializedValidator(ConstraintValidatorManager.java:101) ~[hibernate-validator-5.0.1.Final.jar:5.0.1.Final]
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:125) ~[hibernate-validator-5.0.1.Final.jar:5.0.1.Final]
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:91) ~[hibernate-validator-5.0.1.Final.jar:5.0.1.Final]
at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:85) ~[hibernate-validator-5.0.1.Final.jar:5.0.1.Final]
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:478) ~[hibernate-validator-5.0.1.Final.jar:5.0.1.Final]
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:424) ~[hibernate-validator-5.0.1.Final.jar:5.0.1.Final]
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:388) ~[hibernate-validator-5.0.1.Final.jar:5.0.1.Final]
at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:340) ~[hibernate-validator-5.0.1.Final.jar:5.0.1.Final]
at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:158) ~[hibernate-validator-5.0.1.Final.jar:5.0.1.Final]
at com.MyClass.validate(MyClass.java:48)
Run Code Online (Sandbox Code Playgroud)
您的自定义验证器无法由 Hibernate 实例化,因为 Hibernate 期望验证器具有无参数构造函数(hibernate 文档):
Hibernate Validator 提供的默认 ConstraintValidatorFactory 需要一个公共的无参数构造函数来实例化 ConstraintValidator 实例(请参阅约束验证器)。
所以你基本上有两种可能性:
实现一个自定义ConstraintValidatorFactory,这在链接文档中进行了描述,并且在该工厂中,可以访问 guice 注入器以获取ServiceA并将其传递给构造函数。
删除构造函数并尝试初始化方法内的public MyValidator(ServiceA serviceA)引用。在这里您还需要获得 guice 注射器。ServiceApublic void initialize(final ValidS validS)
要获取注入器,您可以执行以下操作(这不是很好的代码,但不知何故您需要访问注入器)。要存储您的注入器引用,您可以使用单例 - 这里我通过使用枚举来实现它:
public enum GlobalInjector {
INSTANCE;
private Injector injector;
public Injector getInjector() {
return injector;
}
public void setInjector(Injector injector) {
this.injector = injector;
}
}
Run Code Online (Sandbox Code Playgroud)
我不知道你如何初始化 guice,但你可能有一些这样的代码,所以添加代码来存储注入器:
Injector injector = Guice.createInjector(new ConfigurationModule());
GlobalInjector.INSTANCE.setInjector(injector);
Run Code Online (Sandbox Code Playgroud)
那么你的初始化方法将如下所示:
@Override
public void initialize(final ValidS validS) {
Injector injector = GlobalInjector.INSTANCE.getInjector();
if(null != injector) {
serviceA = injector.getInstance(ServiceA.class);
}
}
Run Code Online (Sandbox Code Playgroud)
不要忘记检查GlobalInjector.INSTANCE.getInjector();返回是否不为 null,并且当调用 validate 方法时,请确保返回serviceA不为 null。
注意:我个人不喜欢将注入器存储为全局变量(由单例伪装)的想法,但目前我没有更好的想法。该代码尚未经过测试,因此我希望一切都能按预期工作。
| 归档时间: |
|
| 查看次数: |
2679 次 |
| 最近记录: |