2021-01-15 17:18:07
Аннотации, часть 2: как использовать
Продолжим вчерашнюю тему. Рассмотрим
Retention, и когда пригодится самодельная аннотация.
@Retention определяет, на каком этапе доступна аннотация:
SOURCE - аннотация видна только во время компиляции
CLASS - доступна также в байт-коде
RUNTIME - видна всегда, даже во время работы программы
Доступность выбирается исходя из цели. Поэтому перейдём к кейсам.
Что можно сделать через аннотации?
Объединить уже существующие.
Самый популярный и простой случай. Если в проекте несколько аннотаций часто идут вместе, объедините их в одну. Если у всех компонентов есть обработчики, то больше ничего делать не надо, всё заработает само.
Пример:
@SpringBootApplication - это комбинация
@Configuration,
@EnableAutoConfiguration и
@ComponentScan.
Генерация кода и файлов.
Происходит на этапе компиляции:
Отмечаем код аннотацией
Создаём класс-наследник от
AbstractProcessor. Определяем, на какие аннотации реагировать
Вытаскиваем дополнительную информацию через .class
Deprecated d = Account.class. getAnnotation(Deprecated.class)
Делаем что-то полезное
Включаем процессор в компиляцию. В
maven-compiler-plugin это секция
annotationProcessors.
Для обработки подойдут аннотации с любой RetentionPolicy.
Что получаем:
Долгая компиляция
Специфичное тестирование. Пример
Сложный и запутанный код
Не тратится время на старте приложений
Этот подход используется в библиотеке Lombok, микрофреймворках Quarkus и Micronaut, в Android фреймворке Dagger.
Библиотека Dekorate на основе аннотаций создаёт манифесты для Kubernetes и OpenShift.
Статический анализ.
Алгоритм такой же - создать наследник от
AbstractProcessor, добавить в процесс компиляции.
Примеры: библиотека Google Error Prone ищет в коде ошибки, Hibernate Validator проверяет, что аннотации Hibernate корректно расставлены.
Работа с байт-кодом.
Редкий случай. В байт-коде остаются аннотации с RetentionPolicy.CLASS или RUNTIME.
Создать объекты и прокси-классы.
Доступно для аннотаций с RetentionPolicy.RUNTIME.
Основа работы многих фреймворков: Spring, Hibernate, Java EE. Под работу с аннотациями в рантайме заточены многие библиотеки: Reflections, Spring. Работать с ними удобно и приятно.
Обработка рантайм-аннотаций обычно происходит на старте приложения, поэтому запуск сервиса может занимать несколько минут.
Теперь рассмотрим анти-кейсы, для чего аннотации НЕ нужны:
Отметить код для себя или команды.
Поставить аннотацию
@RefactorASAP легко, но без дальнейших действий это бесполезно. Аннотации нужно обрабатывать, и делать это автоматически.
Чтобы запомнить место в коде, используйте TODO комментарии в Intellij IDEA.
Для бизнес-логики.
Аннотации легко добавить в обход ООП и основной логики. Так можно быстро решить проблему, но долгосрочно это неудачный вариант:
Нельзя контролировать процесс целиком
Сложно писать тесты
Сложно дебажить
Внезапные сайд-эффекты
Частая ситуация на Spring проектах: на старте запускаются десятки
@PostConstruct. Если в процессе возникает ошибка, то найти и исправить её непросто.
Но вообще, чем меньше вы полагаетесь на аннотации, тем лучше.
3.8K views14:18