Spring ベースのプロジェクトでも同じ問題に直面しました。Spring の最良の方法で解決するために、 ConstraintValidator インターフェイスと実装を分割します。たとえば、ドメイン層にはインターフェースしかありません。
public interface UniqueValidator extends ConstraintValidator<Unique, String> {
}
サービス層では、そのインターフェースを実装します:
public class UniqueValidatorJpaImpl implements UniqueValidator {
private EntityManager entityManager;
...
}
次に、UniqueValidatorJpaImpl の Spring Context で Bean を宣言します。
最後に、すべてのスタッフを機能させるために、SpringConstraintValidatorFactory を拡張しました。デフォルトでは、validatedBy で指定されたクラスの新しいインスタンスのみを作成します。最初にSpringコンテキストで対応するタイプのBeanを探すことでそれを拡張しました:
public class SpringConstraintValidatorFactoryEx implements ConstraintValidatorFactory {
private final Logger logger = LoggerFactory.getLogger(SpringConstraintValidatorFactoryEx.class);
@Autowired
private AutowireCapableBeanFactory beanFactory;
public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
T bean = null;
try {
logger.info("Trying to find a validator bean of class " + key.getSimpleName());
bean = this.beanFactory.getBean(key);
} catch (BeansException exc) {
logger.info("Failed to find a bean of class " + key.getSimpleName());
}
if (bean == null) {
try {
logger.info("Creating a new validator bean of class " + key.getSimpleName());
bean = this.beanFactory.createBean(key);
} catch (BeansException exc) {
logger.info("Failed to create a validator of class " + key.getSimpleName());
}
}
if (bean == null) {
logger.warn("Failed to get validator of class " + key.getSimpleName());
}
return bean;
}
}