Интерфейс Validator, насколько я понимаю, вызывается, как только сопоставляется объект (определяется методом public boolean Validator.supports(Class clazz)
).
Однако, похоже, ваша цель состоит в проверке объекта MyClass только в определенное время c, переходящее с вашего уровня персистентности на уровень обслуживания.
Есть несколько способов достичь этого.
Первый и самый очевидный способ - не расширять любые классы, но использовать пользовательский компонент с некоторым понятием функции проверки:
@Component
public class CustomValidator{
public void validate(MyClass target) throws ValidationException {
// validation goes here
if (target.getId() == null) {
throw new ValidationException("Id is missing");
}
}
}
И внедрить / автоматически связать его с вашим сервисным объектом:
@Component
public class MyClassService{
// will be injected in first instance of this component
@Autowired
private CustomValidator validator
public MyClass get(MyClass target) {
try {
validator.validate(target);
return dao.retrieve(target);
} catch (ValidationException) {
// handle validation error
} catch (DataAccessException) {
// handle dao exception
}
}
}
Это имеет то преимущество, что Вы сами можете контролировать валидацию и обработку ошибок. Отрицательной стороной является относительно высокий шаблон.
Однако, если вам нужны разные валидаторы для разных CRUD-операций (или методов обслуживания), вас может заинтересовать функция Spring Validation Groups .
Сначала вы создаете простой интерфейс маркера для каждой операции, которую вы хотите отличать:
interface OnCreate {};
interface OnUpdate {};
Затем все, что вам нужно сделать, это использовать интерфейсы маркера в полях вашего класса сущности. , используя аннотации Bean Validation :
public class MyClass{
@Null(groups = OnCreate.class)
@NotNull(groups = OnUpdate.class)
String id;
}
Чтобы использовать эти группы в своем классе обслуживания, вам нужно будет использовать аннотацию @Validated
.
@Validated
@Service
public class MyService {
@Validated(OnCreate.class)
void validateForCreate(@Valid InputWithGroups input){
// do something
}
@Validated(OnUpdate.class)
void validateForUpdate(@Valid InputWithGroups input){
// do something
}
}
Обратите внимание, что @Validated
применяется как к классу обслуживания, так и к методам. Вы также можете установить группу для всего сервиса, если планируете использовать несколько сервисов.
Я на этот раз чаще всего использую встроенные аннотации Jakarta Bean Validation в сочетании с интерфейсами маркеров, из-за простоты использования и почти без шаблонов, при этом оставаясь несколько гибким и регулируемым.