4

Всем привет. Хотел узнать у знающих, что такое аннотации, и зачем они нужны. До того как начал изучать Java EE у меня было представление, что я знаю, что это такое. Но как дошел до Java EE, увидел, что они применяются везде особенно в JAX-RS и при написании веб сервисов.

Зашел в документацию прочитать про @Context и посмотреть что там внутри. Вот то, что увидел, если кто сможет объяснить синтаксис и саму логику данного кода буду признателен. Если есть ссылки на объяснение буду рад почитать.

 @Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 public @interface Context {
 }
Nofate
  • 34,603
  • 2
    вот почитайте http://www.seostella.com/ru/article/2012/05/19/annotacii-v-java-vvedenie.html – Sergey May 11 '16 at 13:35
  • Прочитал вашу статью.. Абсолютно нечем не помогло. – Maks.Burkov May 11 '16 at 13:56
  • 1
    Не помогло, так не помогло. Что ж, и такое бывает. А статья кстати не моя. Не пишу я статей. – Sergey May 11 '16 at 14:51

2 Answers2

8

Это просто объявление аннотации без какой-либо логики. Как объявить аннотацию, рассказывается в любом учебнике по Java.

По-порядку:

@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})

Аннотация @Target, объявляет элементы исходного кода, к которым можно применить создаваемую аннотацию. В данном случае это: параметры методов (ElementType.PARAMETER), сами методы (ElementType.METHOD) и поля классов (ElementType.FIELD).

@Retention(RetentionPolicy.RUNTIME)

Аннотация @Retention, говорит компилятору, как долго нужно хранить аннотацию в коде. Политика RetentionPolicy.RUNTIME заставляет компилятор сохранить аннотации в .class-файлах и делает их доступными во время выполнения программы через рефлексию.

@Documented

Аннотация @Documented включает создаваемую аннотацию в список элементов исходного кода, для которых генерируется документация (при использовании инструментов генерации документации).

public @interface Context { }

Это, собственно, непосредственно объявление новой аннотации @Context.


Сами по себе аннотации - просто маркеры, никакой работы они не выполняют.

Что касается логики ("магии") аннотаций то обычно это работает так: есть какой-то класс, отвечающий за инициализацию, он пробегает при помощи рефлексии по классам в определенном пакете и ищет какую-то аннотацию. Если находит - экземпляры этого класса подвергаются какой-либо обработке, например полям классов задаются некоторые значения.

В случае с JAX-RS "магией" занимается поставщик реализации (напр. CXF, Jersey, RESTEasy). Где-то в его недрах есть класс, который анализирует аннотации, которыми вы украсили ваши ресурсы и выполняет действия в соответствии со спецификацией JAX-RS. Например, составляет карту соответствий URL-ов конкретным методам, на основе аннотаций @Path и @GET/@PUT/@POST/@DELETE.

Nofate
  • 34,603
  • Nofate - спасибо за ответ!! – Maks.Burkov May 11 '16 at 15:00
  • Nofate Хотел спросить тебя по поводу @Context : Чем отличается от "@QueryParam" "@PathParam" ?
    3.5. Rules of Injection по ссылке: https://jersey.java.net/documentation/latest/user-guide.html#d0e2789 Не могу понять разницу между ними по примерам в документации по ссылке..
    – Maks.Burkov May 11 '16 at 20:05
  • @Maks.Burkov, лучше задайте отдельный вопрос - я поясню с примером. – Nofate May 11 '16 at 21:00
  • @Nofate Также советую почитать про annotation processing http://www.javatronic.fr/articles/2014/10/08/how_does_annotation_processing_work_in_java.html. Компиляцию java классов в байт код основываясь на аннотациях (метапрограммирование ) используя https://docs.oracle.com/javase/8/docs/api/javax/annotation/processing/Processor.html – Denis Vabishchevich Jan 09 '18 at 14:36
  • @DenisVabishchevich мне? зачем? Если вы хотите дополнить информацию - опубликуйте полноценный ответ. – Nofate Jan 09 '18 at 15:48
1

Пример на основе этой статьи:

1) Создаем новый класс-аннотацию:

@Target(value= ElementType.TYPE)
@Retention(value= RetentionPolicy.RUNTIME)
public @interface ControlledObject {
    String name();
}

2) Используем эту аннотацию, т.е. аннотируем класс:

@ControlledObject(name="biscuits")
public class Cookies {
...
}

3) Как работает аннотация: где-то в коде мы проверяем, аннотирован ли наш класс Cookies этой аннотацией, ControlledObject. Если да, то выполняются одни действия, если нет - другие:

Class cl = Class.forName("Cookies");
if(!cl.isAnnotationPresent(ControlledObject.class)){
...
}
else {
...
}
0xdb
  • 51,614