Как я могу найти все классы в пути к классам, которые имеют определенную аннотацию метода?

Я хочу реализовать механизм инициализации, основанный на аннотациях в Java. В частности, у меня есть аннотация, которую я определил:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Initialization {

/**
 * If the eager initialization flag is set to <code>true</code> then the
 * initialized class will be initialized the first time it is created.
 * Otherwise, it will be initialized the first time it is used.
 * 
 * @return <code>true</code> if the initialization method should be called
 *         eagerly
 */
boolean eager() default false;

}

Кроме того, у меня есть интерфейс:

public interface SomeKindOfBasicInterface {}

Я хочу найти каждую реализацию класса SomeKindOfBasicInterface в моем пути к классам, которая имеет аннотацию @Initialization в методе. Я смотрю на инструменты Spring MetaDataReader, которые выглядят как лучший способ отложить загрузку других реализаций SomeKindOfBasicInterface, пока я делаю это... но я не уверен, как выполнить поиск, как я описываю. Какие-нибудь советы?


person Chris R    schedule 18.03.2009    source источник
comment
возможный дубликат сканирования аннотаций Java во время выполнения   -  person Aaron Digulla    schedule 05.06.2012


Ответы (3)


Вы можете использовать Reflections, инструмент анализа метаданных среды выполнения Java. Я использовал его для получения всех подтипов данного типа, но он также может справиться с вашим случаем.

person Kaitsu    schedule 22.03.2009
comment
Я бы настоятельно рекомендовал не использовать отражение или в основном загрузчик классов, если эффективность времени/пространства не вызывает беспокойства. У вас может быть куча классов в пути к классам, и все эти загруженные классы теперь находятся в permgen. Используйте что-то вроде ASM (или библиотеку байт-кода) и просто прочитайте byte[]s, используйте библиотеку ASM, чтобы получить информацию о классе, например. 'это аннотировано с помощью x?' и только тогда загрузите этот класс (если он вам понадобится). - person alphazero; 17.08.2011
comment
@alphazero: Reflections на самом деле не использует java.lang.reflect как таковой. Подобно описанному вами методу, он использует Javassist для чтения метаданных класса, чтобы избежать фактической загрузки классов. - person Nicholas; 07.12.2014
comment
@Nicholas Я бы подумал, что это зависит от реализации JVM. Спецификацию не разглядывал. (в последнее время), поэтому, если это действительно указано (используйте javassist), был бы признателен за ссылку! - person alphazero; 07.12.2014
comment
Обратите внимание на ссылку на Reflections. Это библиотека, а не встроенная JVM. См. ссылку. - person Nicholas; 07.12.2014

Я бы в основном создал реализация BeanPostProcessor, возможно, на основе CommonAnnotationBeanPostProcessor. Затем я настроил компонент -scan, который сканирует путь к классам и выбирает все bean-компоненты, соответствующие вашей спецификации. Когда bean-компонент будет инициализирован, ваш постпроцессор будет запущен.

Я вижу, я предполагаю, что вы ищете бобы. Если это не так, вам, возможно, придется самостоятельно сканировать путь к классам.

person krosenvold    schedule 18.03.2009

Вы можете использовать javassist, чтобы найти аннотации в ваших классах, даже до того, как вы их загрузите, но вам нужно напрямую прочитать файлы .class, что может означать открытие JAR самостоятельно и т. д. Также вам нужно знать, где искать классы. Вы не можете просто запросить у среды выполнения все подклассы вашего BasicInterface.

person Chochos    schedule 18.03.2009