понедельник, 2 января 2017 г.

A programmer: Java #4: Annotations


После долгих (и не очень нужных, видимо) моральных приготовлений возвращаюсь не просто к блогу, но к 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)

То есть, кроме собственно аннотации надо написать соответствующий класс. Другое дело, что у стандартных аннотаций этот класс уже «встроен», как я понял.

Волшебное слово лучше всего описано здесь:
Spring MVC кастомная аннотация для валидации форм (http://devcolibri.com/2664)
и здесь:

Другие материалы по аннотациям:

1. Об аннотациях вообще:

 - The Java™ Tutorials. Lesson: Annotations (http://docs.oracle.com/javase/tutorial/java/annotations/index.html);
 - Аннотации в Java (http://www.quizful.net/post/annotations-in-java);
 - Аннотации в Java - Annotation Types (http://www.javenue.info/post/79);
 - Spring. Аннотации. Конфигурация с помощью аннотаций - 9 - The Basics of Spring Framework (Юрий Ткач) (https://www.youtube.com/watch?v=cIYUAKDnFo4&list=PL6jg6AGdCNaWF-sUH2QDudBRXo54zuN1t&index=9);
 - Аннотации в Hibernate(http://java-course.ru/student/book2/hibernate-annotation/);
 - Как написать свою Аннотацию в Java? (http://devcolibri.com/1253);

2. Об аннотации @Autowired (как пример):

 - Использование аннотации @Autowired в Spring 3 (http://www.seostella.com/ru/article/2012/02/12/ispolzovanie-annotacii-autowired-v-spring-3.html);

3. Валидация:

 -  Проверка данных формы с помощью аннотаций (@Size, @Email и др) в Spring MVC (http://www.seostella.com/ru/article/2012/06/21/proverka-dannyh-formy-s-pomoschyu-annotaciy-size-email-i-dr-v-spring-mvc.html);
 - Spring. Проверка введенных данных (http://spring-projects.ru/guides/validating-form-input/);
 - Как создать собственный валидатор для Sping MVC (http://www.javacore.ru/topic/96-mvc-spring.htm);
 - Проверка входных данных Spring (http://src-code.net/proverka-vxodnyx-dannyx-spring/).


Комментариев нет: