Как создать список классов, помеченных моей пользовательской аннотацией? - PullRequest
31 голосов
/ 05 ноября 2010

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

пс.Например, как реализации JAX-RS находят все классы, помеченные @Path?Я хотел бы использовать тот же механизм.

Ответы [ 8 ]

23 голосов
/ 11 января 2012

Обычно это делается с помощью процесса, называемого сканированием classpath. В общем случае загрузчики классов не позволяют сканировать все классы на пути к классам. Но обычно единственным используемым загрузчиком классов является UrlClassLoader, из которого мы можем получить список каталогов и jar-файлов (см. getURLs ) и открыть их один за другим, чтобы вывести список доступных классов.

Этот подход реализован такими библиотеками, как Scannotation и Reflections .

Другой подход заключается в использовании API-интерфейса Java Pluggable Annotation Processing для написания процессора аннотаций, который будет собирать все аннотированные классы во время компиляции и для создания файла индекса для использования во время выполнения.

Данный механизм реализован в библиотеке ClassIndex .

Использование сканирования пути к классам обычно на два порядка медленнее, чем индексирование во время компиляции. См. этот тест .

10 голосов
/ 14 июля 2013

Я знаю, что это старый вопрос, но я наткнулся на него в своем собственном поиске сканирования пути к классам и нашел другой хороший ответ, поэтому я добавляю его сюда.

В Google Guava есть объект ClassPath , который обеспечивает сканирование пути к классу "наилучшим образом" (что на самом деле и есть любая утилита сканирования пути к классам). Поскольку Guava - это широко распространенная, тщательно поддерживаемая служебная библиотека, это отличный вариант для проектов, которые либо (a) уже используют Guava, либо (b) нуждаются в стабильной библиотеке, на которую можно положиться при сканировании пути к классам.

3 голосов
/ 24 сентября 2015

Вы можете попробовать мою библиотеку FastClasspathScanner :

List<String> classNames = new FastClassPathScanner("com.mypackage")
    .scan()
    .getNamesOfClassesWithAnnotation(Custom.class);
3 голосов
/ 05 ноября 2010

Вы должны взглянуть на Scannotation .

2 голосов
/ 03 сентября 2015

classindex - библиотека сканирования аннотаций во время компиляции, реализованная с использованием процессора аннотаций.

2 голосов
/ 05 ноября 2010

Как вы, наверное, уже знаете, у Java нет способа перечислять все пакеты или классы в каждом пакете. Таким образом, вы должны сделать это «трудным» способом. Опции:

  1. Используйте инструмент, подобный grep, для поиска аннотации. Преимущество: быстро, просто. Недостатки: может возвращать ложные срабатывания (например, классы, где комментарии закомментированы).

  2. Скомпилируйте код и обработайте результат с помощью javap. Это работает на уровне байт-кода [*]. Он дает вам точные результаты, но вывод javap на самом деле не предназначен для автоматической обработки.

  3. Используйте библиотеку байт-кодов, например ASM . Не для слабонервных, но позволяет получить доступ и к другим данным (например, к реализованным интерфейсам, полям и т. Д.) В связи с аннотацией.

  4. Последний вариант: Eclipse использует свой собственный компилятор Java, который может создавать AST из кода Java (даже если код не компилируется). Преимущество перед ASM: Вы получаете модель для кода Java бесплатно. Делает определенные операции более простыми. Не так легко настроить, хотя. См. Мой блог для примера .

[*]: аннотация должна иметь Retention.RUNTIME, чтобы это работало.

0 голосов
/ 05 ноября 2010

Самый простой способ - использовать IDE , как предложил Иисус .

Но вы также можете

Осторожно: все это сложно.Решение AspectJ должно быть самым простым.

0 голосов
/ 05 ноября 2010

Запустите поиск в своей среде IDE для источника. Если вы попытаетесь сделать это для скомпилированных классов, вам придется добавить к ним метод для поддержки этого, даже если вы декомпилируете классы, я не думаю, что аннотации или комментарии будут отображаться .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...