我正在尝试为我的模型类实现自定义验证器,以自动装配我的自定义bean(通过@Component声明)。
在此,我遵循了Spring documentation on that topic。我的AuthenticationFacade对象是根据this tutorial实现的。

但是,在运行测试时,Validator对象中的autowired属性始终为null。这是为什么?

这是我的代码的相关部分:

我的自定义豆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> {
}

最佳答案

我现在通过放弃Validator类的依赖注入来解决此问题,而不是在构造函数中实例化AuthenticationFacadeImpl的实例。
仍然会很有趣,尽管如何将Controller中@Valid的使用与模型中的自定义验证器+ @Autowired属性结合起来,而无需在代码中显式调用Validator ...

09-10 12:48
查看更多