JSR 303 Bean Validation - Почему на геттере, а не на сеттере?

Я не понимаю, почему JSR 303 (проверка bean-компонента) предназначен для методов получения, а не для установки? Не логичнее ли поместить его в метод setter, так как это точка входа в поле, и перед этим должна быть проверена проверка?


person yapkm01    schedule 08.06.2011    source источник
comment
Я не понимаю, почему вы накладываете ограничение на геттер, а не на само поле. Не логичнее ли поставить его на само поле, раз оно, ну, единственное поле?   -  person BalusC    schedule 08.06.2011
comment
@BalusC Ага! Я согласен с тобой. Итак, вопрос в том, если я выполняю проверку в этом одном поле, нужно ли мне также помещать аннотацию в этот метод получения поля? Если нет, то почему вообще существует аннотация для метода получения?   -  person yapkm01    schedule 08.06.2011
comment
Вы определенно не должны ставить его в обоих местах. Это приведет к тому, что поле будет проверено дважды, согласно документам Hibernate.   -  person yuranos    schedule 11.02.2019
comment
Тот же вопрос, установка сеттера или самого поля более интуитивно понятна. Некоторые библиотеки использовали его не в том месте, и теперь я не могу загрузить эти библиотеки из-за исключения проверки.   -  person BlueDolphin    schedule 16.05.2021


Ответы (4)


Аннотирование геттеров не означает, что проверка выполняется при вызове геттера. Он просто используется для идентификации свойства, к которому должно применяться ограничение.

Большим преимуществом наложения ограничений на (обычно общедоступные) геттеры вместо (обычно закрытых) полей является то, что таким образом ограничения являются частью общедоступного API типа. Они даже будут добавлены в сгенерированный JavaDoc. Таким образом, пользователь типа знает, какие ограничения к нему применяются, не заглядывая в его внутреннюю реализацию.

Еще одно преимущество аннотированных геттеров заключается в том, что ограничения могут быть наложены на методы базовых классов или интерфейсов, а также применяться для любых подтипов/реализаций.

person Gunnar    schedule 08.06.2011
comment
Если это так, я не вижу никаких проблем, если ограничения накладываются на общедоступный метод установки. Тот же результат, что и в вашем ответе - person yapkm01; 10.06.2011
comment
Я думаю, что одним из преимуществ использования методов получения вместо методов установки является то, что это позволяет иметь неизменяемые свойства, для которых не существует установщика, при этом получая преимущества ограничений уровня свойства (в отличие от уровня поля), как указано выше. - person Gunnar; 11.06.2011
comment
@ yapkm01, пожалуйста, взгляните на мой ответ. Возникла проблема с методом установки. Вы не всегда можете предсказать правильное поле, используя общедоступный метод установки. - person Kerem Baydoğan; 06.02.2013

Это очень хороший вопрос, на который я никогда не обращал внимания. Но я думаю, что знаю ответ (а также почему я никогда не задавал себе этот вопрос).

Если вы смотрите на это с точки зрения того, что аннотация определяет, где будет происходить проверка, то помещать ее в геттер не имеет смысла. (почему бы не проверить при сохранении самого значения..). Но это не так работает...

Программист должен сообщить системе проверки, какие свойства необходимо проверить. Таким образом, вы можете поместить аннотацию непосредственно в атрибут (что я предпочитаю) или вы можете поместить ее в геттер. Оба они означают операцию чтения. Framework должен прочитать все атрибуты вашего класса, которые должны быть проверены. Так что в этом случае ставить сеттер вообще не имеет смысла. Ключ к пониманию - это перспектива...

Я надеюсь, что это имеет смысл.

person uncaught_exceptions    schedule 08.06.2011
comment
Да, это не имеет смысла, если вы посмотрите на это таким образом. Я не думаю, что позиционирование вашей аннотации на геттере выполняет проверку на геттере. Мы просто помечаем этот атрибут как нечто, что фреймворк должен проверить. - person uncaught_exceptions; 08.06.2011
comment
я понимаю, что вы пытаетесь сказать. Насколько я понимаю в отношении жизненного цикла JSF, если на этапе проверки процесса возникает ошибка проверки, та же страница отображается повторно. Разве не следует вызывать метод установки для проверки? Метод получения вызывается только на этапе рендеринга страницы. Зачем выполнять проверку на этапе рендеринга страницы? На мой взгляд, на этом этапе бессмысленно выполнять проверку, поскольку... ну, теперь все хорошо, и, следовательно, указанная страница отображается для отображения. - person yapkm01; 08.06.2011
comment
Это потому, что есть случаи, когда нет метода установки. Сеттер не будет включен, скажем, в свойство только для чтения. - person ialexander; 20.10.2016

Рассмотрим этот код:

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)

Аннотация не может идентифицировать поле, глядя на измененное поле, поскольку их может быть несколько.

person Kerem Baydoğan    schedule 10.06.2011
comment
отражение не смотрит на реализацию метода, оно смотрит на имя геттера/сеттера и сопоставляет его с полем - person Brad Cupit; 28.02.2014

Bean Validation называется так не просто так. Он применяется к инициализированному bean-компоненту. Итак, сначала вы инициализируете его всем, что у вас есть, затем вы передаете его (или он передается явно) реализации Bean Validation, которая будет полагаться на аннотации проверки при доступе к полям. В случае Spring обработка проверки MVC начинается с:

result = execVal.validateParameters(
                invocation.getThis(), methodToValidate, invocation.getArguments(), groups);

внутри MethodValidationInterceptor. С этого момента он передается реализации проверки, в большинстве случаев Hibernate. invocation.getArguments() будет содержать все аргументы метода, уже инициализированные с заданными значениями, независимо от аннотаций проверки.

person yuranos    schedule 11.02.2019