我有一个基于Spring的webapp。我在控制器中使用了几个带有注解@ Repository,@ Transactional的存储库类。那部分工作正常。
我创建了一个自定义约束验证器,它必须访问存储库。现在,我不明白为什么存储库为空。我尝试使用@Component注释对验证器进行注释。包含所有这些类的基本程序包位于xml的一部分中。因此,我还应该采取其他措施来确保存储库依赖项注入正常工作。这就是我的约束验证器的样子。
public class DonorTypeExistsConstraintValidator implements ConstraintValidator<DonorTypeExists, DonorType> { @Autowired private DonorTypeRepository donorTypeRepository; @Override public void initialize(DonorTypeExists constraint) { } public boolean isValid(DonorType target, ConstraintValidatorContext context) { System.out.println("donorType: " + target); if (target == null) return true; try { if (donorTypeRepository.isDonorTypeValid(target.getDonorType())) return true; } catch (Exception e) { e.printStackTrace(); } return false; } public void setDonorRepository(DonorTypeRepository donorTypeRepository) { this.donorTypeRepository = donorTypeRepository; } }
更新资料
程序包扫描配置:
<context:annotation-config /> <!-- Configures the @Controller programming model --> <mvc:annotation-driven /> <context:component-scan base-package="controller" /> <context:component-scan base-package="repository" /> <context:component-scan base-package="model" /> <context:component-scan base-package="viewmodel" />
此类在包model.donortype中。该存储库位于软件包存储库中。
更令人费解的是,删除所有插入前的侦听器(在本例中为BeanValidationEventListener)可解决自动装配问题。这使事情更加复杂。
我什至没有按下面的答案中所述插入BeanValidationEventListener。这实际上与这里的建议相反: JSR-303依赖项注入和Hibernate
@Override public void integrate(Configuration configuration, SessionFactoryImplementor implementor, SessionFactoryServiceRegistry registry) { logger.info("Registering event listeners"); System.out.println("here"); // you can add duplication strategory for duplicate registrations final EventListenerRegistry eventRegistry = registry.getService(EventListenerRegistry.class); // prepend to register before or append to register after // this example will register a persist event listener eventRegistry.prependListeners(EventType.PERSIST, EntitySaveListener.class); eventRegistry.appendListeners(EventType.MERGE, EntitySaveListener.class); Iterator<PreInsertEventListener> iter = eventRegistry.getEventListenerGroup(EventType.PRE_INSERT).listeners().iterator(); while (iter.hasNext()) { PreInsertEventListener el = iter.next(); System.out.println(el.getClass()); BeanValidationEventListener listener = (BeanValidationEventListener) el; System.out.println(listener); iter.remove(); } }
我正在使用JPA。我有JPA实体的支持表格。在控制器中,我使用InitBinder实例化自定义验证器binder.setValidator(new EntityBackingFormValidator(binder.getValidator()));。这是为此的代码:https : //github.com/C4G/V2V/blob/87dc266043f6d623c101d947a88fa0b0ad536355/src/controller/CollectedSampleController.java
binder.setValidator(new EntityBackingFormValidator(binder.getValidator()));
此自定义验证器在默认验证器上调用验证,并让范围进行一些自定义验证。 https://github.com/C4G/V2V/blob/87dc266043f6d623c101d947a88fa0b0ad536355/src/model/collectedsample/CollectedSampleBackingFormValidator.java
我在实体中使用注释来创建约束。除了默认约束外,我还需要定义约束来检查多对一映射另一侧的实体是否存在。这是自定义约束验证器。 https://github.com/C4G/V2V/blob/87dc266043f6d623c101d947a88fa0b0ad536355/src/model/donor/DonorExistsConstraintValidator.java
现在,此自定义约束验证器中的自动装配库为空。我正在尝试在我的CustomIntegrator中自定义代码,该代码位于 https://github.com/C4G/V2V/blob/87dc266043f6d623c101d947a88fa0b0ad536355/src/interceptor/CustomIntegrator.java
以及此处提供的xml配置文件 https://github.com/C4G/V2V/blob/87dc266043f6d623c101d947a88fa0b0ad536355/war/WEB- INF/v2v-servlet.xml
希望实际的代码将帮助您回答我的问题。谢谢!
您正在使用哪个 ValidatorFactory 。还是换一种说法,您对Bootstrap Bean验证很感兴趣?默认情况下,Bean验证(和Hibernate Validator作为参考实现)不会将依赖项注入 ConstraintValidator 实例中。至少在Bean Validation 1.0中。
为了启用依赖注入,您必须配置一个自定义 ConstraintValidatorFactory 。Spring提供 SpringConstraintValidatorFactory ,这是使用 LocalValidatorFactoryBean 时的默认设置- 请参见http://static.springsource.org/spring/docs/3.0.0.RC3/reference/html/ch05s07.html
另外,您在使用JPA吗?我假设是这样,在这种情况下,将自动对生命周期事件进行自动验证。可以尝试使用属性 javax.persistence.validation.mode 并将其设置为NONE,而不是尝试删除事件侦听器。我想知道是否在基于生命周期的验证中使用了正确的验证器。
这完全取决于您的整体Spring配置和使用。