Esta fábrica permite desacoplar a Constraint da implementação concreta do ConstraintValidator, possibilitando que aquela esteja fisicamente separada em projeto distinto do que conterá a implementação do validador acionado por ela, o que pode ser útil em sistemas compostos por múltiplos módulos independentes e que compartilham dados, aonde pode ser interessante, por exemplo, concentrar entidades e DTOs, classes normalmente marcadas com uma ou mais constraint para validar seus dados, em um projeto separado do negócio e da apresentação, o qual será compartilhado como dependência entre os vários módulos que utilizarão aqueles dados e com menor acoplamento direto entre os módulos. Neste cenário a validação das entidades do módulo "FOO" pode ser acionado a partir do módulo "BAR" através, por exemplo, de um serviço EJB.
Segundo especificado na API a implementação de validadores customizados segue o seguinte modelo:
Constraint
@Target( { METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Constraint(validatedBy = MyValidator.class)
@Documented
public @interface MyConstraint {
String message() default "My message";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Validador
public class MyValidator implements ConstraintValidator<MyConstraint, String> {
public void initialize(MyConstraint constraintAnnotation) {
...
}
public boolean isValid(String object, ConstraintValidatorContext constraintContext) {
...
}
}
Com o uso do componente, é possível atribuir uma interface à constraint como visto a seguir:
Constraint
@Target( { METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Constraint(validatedBy = IMyValidator.class)
@Documented
public @interface MyConstraint {
String message() default "My message";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Interface do Validador
public interface IMyValidator extends ConstraintValidator<MyConstraint, String> {
}
Validador
public class MyValidator implements IMyValidator {
public void initialize(MyConstraint constraintAnnotation) {
...
}
public boolean isValid(String object, ConstraintValidatorContext constraintContext) {
...
}
}