I'm trying to implement a custom validator for my model classes that autowires a custom bean of mine (declared via @Component
).
In this, I followed the Spring documentation on that topic. My AuthenticationFacade
object is implemented according to this tutorial.
When running my tests, however, the autowired attribute in the Validator
object is always null
. Why is that?
Here are the relevant parts of my code:
My custom bean, AuthenticationFacadeImpl.java
@Component
public class AuthenticationFacadeImpl implements AuthenticationFacade {
boolean hasAnyRole(Collection<String> roles) {
// checks currently logged in user roles
}
}
My custom constraint, 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 {};
}
My custom validator, 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));
}
}
The model class, Article.java
@Entity
public class Article {
// ...
@HasAnyRole({"EDITOR", "ADMIN"})
private String title;
// ...
}
The service object, 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;
}
The Errors
object that gets fed into the createArticle
method is intended to come from the Spring controller, which gets fed a model object with the @Valid
annotation.
The repository, ArticleRepository.java
, uses Spring Data JPA's JpaRepository
public interface ArticleRepository extends JpaRepository<Article, Long> {
}