В методе postProcessBeforeInitialization не доступны собственные аннотации
Пытаюсь реализовать свою собственную аннотацию.
Основная логика будет в postProcessAfterInitialization
Для того чтобы определить аннотированные бины, реализовал postProcessBeforeInitialization так:
private val map = mutableMapOf<String, Class<Any>>()
override fun postProcessBeforeInitialization(bean: Any, beanName: String): Any? {
val beanClass = bean.javaClass
if (beanClass.isAnnotationPresent(MyAnnotation::class.java)) {
map[beanName] = beanClass
}
return bean
}
Проблема в том, что по задумке моя аннотация должна ставиться над main-классом, который в свою очередь аннотирован @SpringBootAnnotation и видимо из-за этого в методе postProcessBeforeInitialization мне в качестве бина приходит уже прокси, а не оригинальный класс.
Соответсвенно прокси аннотирована только аннотацией @SpringBootAnnotation, моей аннотации над прокси-классом нет, мой вопрос - можно ли как-то получить оригинал класса, который аннотирован с помощью @SpringBootAnnotation ?
Знаю, что можно получить оригинальный класс из прокси с помощью bean.javaClass.superclass но не уверен, что это очень хорошее решение
Ответы (1 шт):
Аннотация потерялась не из-за прокси.
Это не является причиной того, что вы не можете ее найти во время выполнения программы.
В чем причина?
Все дело в стратегии хранения аннотаций.
Всего есть три стратегии:
CLASS
Аннотации записываются в файл класса(.class) компилятором, но не доступны во время выполнения виртуальной машине.
RUNTIME
Аннотации записываются в файл класса(.class) компилятором и доступны во время выполнения, а также доступны для рефлексии.
SOURCE
Аннотации исключаются во время компиляции и не попадают в файл класса(.class). Соответственно они не доступны во время выполнения.
Значением по умолчанию является CLASS, что значит что по умолчанию аннотация не доступны во время выполнения.
Что делать?
Для того, чтобы сделать ее доступной и иметь возможность читать ее с помощью рефлексии, необходимо изменить стратегию хранения.
Сделать это можно проставив аннотацию Retention со значением RUNTIME над Вашей аннотацией
@Retention(RetentionPolicy.RUNTIME)
//ниже объявление вашей аннотации