После
долгих (и не очень нужных, видимо)
моральных приготовлений возвращаюсь
не просто к блогу, но к Java. Сегодняшняя
тема — аннотации.
Когда
я учился Java, я видел код — переменные,
методы, циклы и прочее, а вот некоторых
вещей не видел, и встретил впервые только
на курсах. В числе этих невиданных штук
были аннотации — это такие надписи со
значком @. Очевидно, они для чего-то
нужны. Иногда мне рассказывали, для
чего, но вот как они работают, я понять
не мог очень долго. Мне посоветовали
написать аннотацию самому. Но результативно
помочь мне в этом лучше всего остального
смогла книга Уоллс К. Spring в действии.
– М.: ДМК Пресс, 2013 и
одно волшебное слово. Про книгу напишу
в следующий раз, а про волшебное слово
сейчас.
Дело
в том, что программирование продвинулось
уже достаточно далеко, чтобы автоматизировать
многие действия, а не описывать их в
коде каждый раз заново. Достаточно того,
чтобы указать, что в данном месте должно
выполняться некоторое действие, которое
описано (реализовано) в другом месте.
Аннотации как раз и являются (среди
прочего) такими указателями:
@MyAnnotation(здесь
могут быть описаны параметры аннотации)
Аннотации
основаны на механизме интерфейса,
поэтому ключевое слово @interface и будет
свидетельствовать о том, что это
аннотация:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public
@interface MyAnnotation {
String
info() default "";
int
val() default 42;
}
Здесь
@Target(ElementType.METHOD) и @Retention(RetentionPolicy.RUNTIME)
указывают, что аннотация применима к
методу и что она исполняется при
выполнении программы, соответственно
(разумеется, предусмотрены и другие
опции). Для того, чтобы это работало,
надо импортировать соответствующие
пакеты:
import
java.lang.annotation.ElementType;
import
java.lang.annotation.Retention;
import
java.lang.annotation.RetentionPolicy;
import
java.lang.annotation.Target;
В
дальнейшем таким же образом нужно будет
импортировать пакет с нашей аннотацией,
чтобы она была рабочей.
Как
уже говорилось, значения описанных в
аннотации переменных (если они иные,
чем по умолчанию) могут указываться при
применении аннотации.
Данная
аннотация пока что только сообщает
некоторую информацию, но большинство
аннотаций «работают», что-то делают.
Вот тут и была самая большая загвоздка
для меня: где, собственно, реализация?
Где находится кусок кода, который
«встраивается» там, где аннотация должна
выполнять какие-то действия. Я долго не
мог этого понять, пока мне не посоветовали
написать не просто какую-то аннотацию,
а, например, аннотацию для валидации —
то есть для проверки, правильно ли что-то
введено пользователем (нет ли недопустимых
значений и т.п. - если правильно, то ОК,
если нет, то — вывод соответствующего
сообщения, например).
Один
из типичных примеров аннотаций для
валидаций в коде выглядит так:
@Size(min=3,
max=20, message="Username must be between 3 and 20
characters long.")
Когда
я стал разбираться, как устроены аннотации
для валидаций, то выяснилось, что, кроме
обычных уже вещей, они содержат еще одну
аннтоацию для аннотаций (вот заветное
волшебное слово): @Constraint. После него и
указывается файл, в котором и происходит
соответствующая проверка:
@Constraint(validatedBy
= BlaBlaBlaValidator.class)
То
есть, кроме собственно аннотации надо
написать соответствующий класс. Другое
дело, что у стандартных аннотаций этот
класс уже «встроен», как я понял.
Волшебное
слово лучше всего описано здесь:
и здесь:
Другие
материалы по аннотациям:
1.
Об аннотациях вообще:
2.
Об аннотации @Autowired (как пример):
3.
Валидация: