Я не понимаю, почему JSR 303 (проверка bean-компонента) предназначен для методов получения, а не для установки? Не логичнее ли поместить его в метод setter, так как это точка входа в поле, и перед этим должна быть проверена проверка?
JSR 303 Bean Validation - Почему на геттере, а не на сеттере?
Ответы (4)
Аннотирование геттеров не означает, что проверка выполняется при вызове геттера. Он просто используется для идентификации свойства, к которому должно применяться ограничение.
Большим преимуществом наложения ограничений на (обычно общедоступные) геттеры вместо (обычно закрытых) полей является то, что таким образом ограничения являются частью общедоступного API типа. Они даже будут добавлены в сгенерированный JavaDoc. Таким образом, пользователь типа знает, какие ограничения к нему применяются, не заглядывая в его внутреннюю реализацию.
Еще одно преимущество аннотированных геттеров заключается в том, что ограничения могут быть наложены на методы базовых классов или интерфейсов, а также применяться для любых подтипов/реализаций.
Это очень хороший вопрос, на который я никогда не обращал внимания. Но я думаю, что знаю ответ (а также почему я никогда не задавал себе этот вопрос).
Если вы смотрите на это с точки зрения того, что аннотация определяет, где будет происходить проверка, то помещать ее в геттер не имеет смысла. (почему бы не проверить при сохранении самого значения..). Но это не так работает...
Программист должен сообщить системе проверки, какие свойства необходимо проверить. Таким образом, вы можете поместить аннотацию непосредственно в атрибут (что я предпочитаю) или вы можете поместить ее в геттер. Оба они означают операцию чтения. Framework должен прочитать все атрибуты вашего класса, которые должны быть проверены. Так что в этом случае ставить сеттер вообще не имеет смысла. Ключ к пониманию - это перспектива...
Я надеюсь, что это имеет смысл.
Рассмотрим этот код:
public class BeanValidation {
private int nameSetCount = 0;
private int nameGetCount = 0;
private String name;
public String getName() {
this.nameGetCount++;
return name;
}
public void setName(String name) {
this.nameSetCount++;
this.name = name;
}
}
Поместите аннотацию поверх private String name;
Аннотация легко идентифицирует поле, просто взглянув на поле.
Поместите аннотацию поверх public String getName()
Аннотация легко идентифицирует поле, просто взглянув на возвращенное поле.
Поместите аннотацию поверх public void setName(String name)
Аннотация не может идентифицировать поле, глядя на измененное поле, поскольку их может быть несколько.
Bean Validation называется так не просто так. Он применяется к инициализированному bean-компоненту. Итак, сначала вы инициализируете его всем, что у вас есть, затем вы передаете его (или он передается явно) реализации Bean Validation, которая будет полагаться на аннотации проверки при доступе к полям. В случае Spring обработка проверки MVC начинается с:
result = execVal.validateParameters(
invocation.getThis(), methodToValidate, invocation.getArguments(), groups);
внутри MethodValidationInterceptor
. С этого момента он передается реализации проверки, в большинстве случаев Hibernate. invocation.getArguments()
будет содержать все аргументы метода, уже инициализированные с заданными значениями, независимо от аннотаций проверки.