我正在尝试为我的模型类实现一个自定义验证器,它自动装配我的自定义bean(通过@Component
声明)。
在此,我跟随Spring documentation on that topic。我的AuthenticationFacade
对象是根据this tutorial实现的。
但是,在运行测试时,Validator
对象中的自动装配属性始终为null
。那是为什么?
以下是我的代码的相关部分:
我的自定义bean ,AuthenticationFacadeImpl.java
@Component
public class AuthenticationFacadeImpl implements AuthenticationFacade {
boolean hasAnyRole(Collection<String> roles) {
// checks currently logged in user roles
}
}
我的自定义约束,HasAnyRoleConstraint.java
@Constraint(validatedBy = HasAnyRoleConstraintValidator.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface HasAnyRole {
String[] value();
String message() default "{HasAnyRole}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
我的自定义验证器,HasAnyRoleConstraintValidator.java
@Component
public class HasAnyRoleConstraintValidator implements ConstraintValidator<HasAnyRole, Object> {
@Autowired
AuthenticationFacade authenticationFacade;
private String[] roles;
@Override
public void initialize(HasAnyRole hasAnyRole) {
this.roles = hasAnyRole.value();
}
@Override
public boolean isValid(Object target, ConstraintValidatorContext constraintValidatorContext) {
return target == null || authenticationFacade.hasAnyRole(Arrays.asList(this.roles));
}
}
模型类,Article.java
@Entity
public class Article {
// ...
@HasAnyRole({"EDITOR", "ADMIN"})
private String title;
// ...
}
服务对象,ArticleServiceImpl.java
@Service
public class ArticleServiceImpl implements ArticleService {
@Autowired
private ArticleRepository articleRepository;
@Autowired
private AuthenticationFacade authenticationFacade;
@Autowired
private Validator validator;
@Override
@PreAuthorize("hasAnyRole('ADMIN', 'EDITOR')")
public boolean createArticle(Article article, Errors errors) {
articleRepository.save(article);
return true;
}
Errors
方法的createArticle
对象是来自Spring控制器,它被赋予一个带有@Valid
注释的模型对象。
存储库,ArticleRepository.java
使用Spring Data JPA的JpaRepository
public interface ArticleRepository extends JpaRepository<Article, Long> {
}
答案 0 :(得分:0)
我现在通过抛弃Validator类的Dependency Injection来解决这个问题,而不是在构造函数中实例化AuthenticationFacadeImpl
的实例。
仍然有趣,但如何将控制器中@Valid
的使用与模型中的自定义验证器+ @Autowired
属性相结合,而无需在代码中明确地调用验证器...
答案 1 :(得分:0)
如果您的验证器在Spring上下文之外被实例化,那么您可以使用Spring的AOP @Configurable魔法在上下文中注册它并获得自动装配工作。您需要的只是使用HasAnyRoleConstraintValidator
注释@Configurable
并启用编译时间或加载时间方面的编织。