Когда вызывается код процессора пользовательской аннотации Java? (сохранение во время выполнения)

#java #annotations #processor

Вопрос:

Я знаю, что пользовательские аннотации Java нуждаются в объявлении @interface полуинтерфейса и коде процессора (в некоторых текстах он называется кодом потребителя), который определяет фактическую бизнес-логику, лежащую в основе аннотации. Пока все ясно, но мой вопрос в том, где/когда именно вызывается код процессора и кем? Я имею в виду, генерирует ли компилятор Java код, который вызывает все процессоры аннотаций, например, во время загрузки класса? или программист сам решает, когда вызывать коды своих процессоров для своих пользовательских аннотаций? например, @GetMapping("/users") в каком-либо методе API сервлета сообщает, что запросы с /пользователями в их пути запроса должны быть доставлены в этот метод. таким образом, у него есть какой-то процессор за сценой, который должен быть вызван для хранения этой конфигурации отображения где-то, но когда и кто вызывает этот процессор? Я думаю, что мой вопрос имеет смысл только в аннотациях с. @Retention(RetentionPolicy.RUNTIME) Спасибо

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

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

2. @Holger Я не имел в виду, что мы должны написать процессор для аннотаций сервлетов или что-то в этом роде, я знаю, что Spring Web уже написал процессор для аннотации. моя проблема в том, что когда вызывается этот процессор? и кем?

3. Может быть, сначала нам следует уточнить, что вы понимаете под названием «процессор».

Ответ №1:

Annotation Как следует из названия, это дополнительная информация (или поведение). По умолчанию эта информация не обрабатывается и не используется для изменения какого-либо поведения. Должна быть какая-то сущность для обработки аннотации.

Политика хранения сообщает компилятору Java об области действия аннотации. То есть, требуется ли дополнительная информация для обработки во время выполнения или во время компиляции.

Для обработки во время компиляции annotation processors они подключаются к процессу компиляции с помощью -processor флага. Для обработки во время выполнения отражение (например, это) используется для доступа к дополнительной информации.

@GetMapping(«/пользователи») в каком-либо методе указывает API сервлета сопоставлять запросы с /пользователями в их пути запроса,

Просто наличие аннотации не приводит к такому поведению. Пружинный каркас (многое упрощающий) —

  • устанавливается в качестве конечной точки сервлета для /* . См. раздел FrameworkServlet
  • перечисляет методы, снабженные аннотациями с GetMapping использованием отражения
  • использует аннотированную информацию для заполнения сопоставления URL-адресов методам.
  • при обработке запросов использует сопоставление для маршрутизации к предполагаемому методу.

Один простой трюк, чтобы понять поток (да, Java иногда слишком волшебна), — это установить точки останова и посмотреть на стек вызовов.

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

1. спасибо за ваш ответ, однако вопрос не в функциональности процессора или аннотации, а только в том, когда и кем вызывается процессор? пример ответа: он запускается во время выполнения Java и во время загрузки класса. или: он вызывается самой библиотекой и в произвольное время.

Ответ №2:

Процессор аннотаций запускается во время компиляции. При вызове javac пользователь передает параметр -processor командной строки, а затем javac вызывает процессор. Обработчик аннотаций может выдавать ошибки, создавать файлы (в том числе файлы кода Java) и даже изменять существующий код. В дополнение к документации Oracle, приведенной выше, вы, возможно, захотите ознакомиться с учебником, таким как Baeldung.

Некоторые фреймворки напрямую интерпретируют аннотации, поэтому вам не нужно писать свой собственный процессор аннотаций.

Чтобы повлиять на поведение во время выполнения, ваш код может рефлексивно считывать аннотации; в этом случае во время компиляции не запускается процессор аннотаций.

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

1. вы имеете в виду, что компилятор не просто компилирует процессор(генерирует байтовый код)? и он также управляет им? это то, что меня действительно поражает 🙂

2. Также спасибо за статью Бельгунга, однако эта статья погружается в @Retention(Политика сохранения. ИСТОЧНИК) пример, однако мой вопрос в основном касается @Retention(Политика сохранения. ВРЕМЯ ВЫПОЛНЕНИЯ) дела.

3. Вы отредактировали свой вопрос, чтобы сказать, что он касается сохранения времени выполнения, но это не меняет ни вопроса, ни ответа. Термин «обработка аннотаций» относится к обработке во время компиляции. Обработка аннотаций во время компиляции применима независимо от того, каково сохранение аннотации.

4. Хорошо, давайте рассмотрим пример, @GetMapping должен сохранить сопоставление между некоторым текстом в пути http-запроса и методом в нашем контроллере, верно? поскольку, согласно вашему комментарию, он запускается во время компиляции, он должен генерировать какой-то внешний файл для сопоставлений, верно? и во время выполнения веб-сервер Spring Boot прочитает файл, чтобы перенаправить запросы на предназначенные для них методы контроллера. но вопрос в том, когда в первый раз читается упомянутый внешний файл? это при первом http-запросе? или в какой-то момент при запуске нашего приложения Spring Boot происходит какая-то инициализация?