Как получить список классов, которые аннотируются с тем же аннотацией, во время выполнения [duplicate]

В Java 8 (выпущен в марте 2014 года) можно писать повторяющиеся / дублированные аннотации. См. [D0] http://docs.oracle.com/javase/tutorial/java/annotations/repeating.html .

30
задан yegor256 5 November 2010 в 16:59
поделиться

8 ответов

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

  1. Используйте инструмент, например grep, для поиска аннотации. Преимущество: быстрая, простая. Недостатки: можно вернуть ложные срабатывания (например, классы, в которых комментируется аннотация).
  2. Скомпилируйте код и обработайте результат с помощью javap. Это работает на уровне байт-кода [*]. Он дает точные результаты, но вывод javap на самом деле не предназначен для автоматической обработки.
  3. Используйте библиотеку байт-кода, например ASM . Не для слабонервных, но он также позволяет вам получить доступ к другим данным (например, реализованные интерфейсы, поля и т. Д.) В отношении аннотации.
  4. Последняя опция: Eclipse использует свой собственный компилятор Java, который может создавать АСТ от Java-кода (даже если код не компилируется). Преимущество над ASM: вы бесплатно получаете модель для Java-кода. Делает определенные операции более простыми. Но так легко настроить. См. мой блог для примера .

[*]: аннотация должна иметь Retention.RUNTIME для этого.

2
ответ дан Aaron Digulla 16 August 2018 в 11:22
поделиться
  • 1
    Первый вариант = arggghh. Все остальные: +1 – Sean Patrick Floyd 5 November 2010 в 17:00
  • 2
    Какие из ваших вариантов реализации JAX-RS используют, например, Джерси, чтобы найти все @Path -номинированные классы? – yegor256 5 November 2010 в 17:49
  • 3
    Позаботьтесь о том, чтобы доказать свою претензию, что нет способа? Особенно в свете библиотеки, с которой я связался в своем ответе? – meriton 5 November 2010 в 19:16
  • 4
    Правильно; обратите внимание, что путь к классам во время выполнения может отличаться от такового во время компиляции. Таким образом, сканирование по классам является хрупким. Изучение системного свойства java.class.path может привести к неправильным результатам, когда ваш код работает на сервере приложений или когда вы используете пользовательские загрузчики классов. Не все загрузчики классов позволяют проверять пути, из которых загружаются классы. Поэтому мое утверждение: у Java нет API для этого. Вы должны прибегнуть к какой-то взлому. – Aaron Digulla 8 November 2010 в 14:21
  • 5
    Я просто хочу указать, что вы можете получить эту информацию во время выполнения, но вам нужно использовать отражение для создания «классов», свойство public на используемом ClassLoader. Это не рекомендуется и может ломаться в новых версиях Java (нет гарантии, что частный метод будет в следующей версии). Дополнительная информация в stolenkid.wordpress.com/2009/03/11/browse-classloader – Hoffmann 8 April 2013 в 17:15

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

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

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

0
ответ дан Community 16 August 2018 в 11:22
поделиться

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

0
ответ дан Keibosh 16 August 2018 в 11:22
поделиться

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

3
ответ дан keuleJ 16 August 2018 в 11:22
поделиться
  • 1
    Кажется хорошим вариантом. Я попробую позже – rpax 27 July 2016 в 05:44

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

List<String> classNames = new FastClassPathScanner("com.mypackage")
    .scan()
    .getNamesOfClassesWithAnnotation(Custom.class);
3
ответ дан Luke Hutchison 16 August 2018 в 11:22
поделиться

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

1
ответ дан snorbi 16 August 2018 в 11:22
поделиться

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

Этот подход реализуется такими библиотеками, как Scannotation и Reflections .

Еще один подход заключается в использовании Java Plug-and-end API обработки аннотации ], чтобы написать обработчик аннотации, который будет собирать все аннотированные классы во время компиляции и создавать файл индекса для использования во время выполнения.

Вышеупомянутый механизм реализован в библиотеке ClassIndex .

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

21
ответ дан Sławek 16 August 2018 в 11:22
поделиться

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

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

10
ответ дан Thomas 16 August 2018 в 11:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: