Каков наилучший способ поиска аннотированного класса по всему пути к классам?
Я делаю библиотеку и хочу разрешить пользователям аннотировать свои классы, поэтому при запуске веб-приложения мне нужно просканировать весь путь к классу для определенной аннотации.
Знаете ли вы библиотеку или средство Java для этого?
Изменить: я думаю о чем-то вроде новой функциональности для веб-служб Java EE 5 или EJB. Вы аннотируете свой класс с помощью @WebService
или, @EJB
и система находит эти классы во время загрузки, чтобы они были доступны удаленно.
источник
@Conditional
аннотаций. Таким образом, если значение класса@Conditional
возвращает false, оно не будет возвращеноfindCandidateComponents
, даже если оно соответствует фильтру сканера. Это бросило меня сегодня - я закончил тем, что использовал решение Джонатана ниже.BeanDefinition
объект не предоставляет способ получить класс напрямую. Кажется, самое близкое,getBeanClassName
что возвращает полное имя класса, но точное поведение этого метода неясно. Кроме того, неясно, в каком загрузчике класса был найден класс.Class<?> cl = Class.forName(beanDef.getBeanClassName());
farenda.com/spring/find-annotated-classesИ еще одно решение - Google размышления .
Быстрый обзор:
источник
new Reflections("my.package").getTypesAnnotatedWith(MyAnnotation.class)
, самое лучшее.Вы можете найти классы с любой данной аннотацией с помощью ClassGraph , а также искать другие критерии, представляющие интерес, например, классы, которые реализуют данный интерфейс. (Отказ от ответственности, я являюсь автором ClassGraph.) ClassGraph может построить абстрактное представление всего графа классов (все классы, аннотации, методы, параметры методов и поля) в памяти для всех классов на пути к классам или для классов в белые списки, и вы можете запросить этот граф классов, как вы хотите. ClassGraph поддерживает больше механизмов спецификации classpath и загрузчиков классов, чем любой другой сканер, а также беспрепятственно работает с новой системой модулей JPMS, поэтому если вы основываете свой код на ClassGraph, ваш код будет максимально переносимым. Смотрите API здесь.
источник
Reflections
. Также, если вы используете guava / etc и хотите изменить коллекции, просто как пирог. Замечательные комментарии внутри тоже.Если вы хотите действительно легкий вес (без зависимостей, простой API, файл jar 15 Кб) и очень быстрое решение, взгляните на
annotation-detector
страницу https://github.com/rmuller/infomas-asl.Отказ от ответственности: я автор.
источник
Вы можете использовать Java Pluggable Annotation Processing API для написания процессора аннотаций, который будет выполняться во время процесса компиляции и будет собирать все аннотированные классы и создавать индексный файл для использования во время выполнения.
Это самый быстрый способ сделать аннотированное обнаружение классов, потому что вам не нужно сканировать путь к классам во время выполнения, что обычно является очень медленной операцией. Также этот подход работает с любым загрузчиком классов, а не только с URLClassLoaders, обычно поддерживаемыми сканерами времени выполнения.
Вышеуказанный механизм уже реализован в ClassIndex библиотеке .
Чтобы использовать его, аннотируйте свою пользовательскую аннотацию с помощью @IndexAnnotated meta-annotation. Во время компиляции будет создан индексный файл: META-INF / annotations / com / test / YourCustomAnnotation, в котором перечислены все аннотированные классы. Вы можете получить доступ к индексу во время выполнения, выполнив:
источник
Это слишком поздно, чтобы ответить. Я бы сказал, что лучше пойти по таким библиотекам, как ClassPathScanningCandidateComponentProvider или как Scannotations
Но даже после того, как кто-то захочет попробовать это с помощью classLoader, я написал несколько самостоятельно, чтобы напечатать аннотации классов в пакете:
А в файле конфигурации вы помещаете имя пакета и разбираете его в классе.
источник
С помощью Spring вы также можете просто написать следующее, используя класс AnnotationUtils. то есть:
Для получения дополнительной информации и различных методов ознакомьтесь с официальными документами: https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/annotation/AnnotationUtils.html.
источник
null
значение в качестве второго параметра (который определяет класс, в котором Spring наследует иерархию наследования для поиска класса, который использует аннотацию), вы все равно получитеnull
ответ в соответствии с реализацией.Zapp замечательно комментирует все эти ответы:
источник
В Classloader API нет метода «перечисления», потому что загрузка классов - это действие «по требованию» - у вас обычно есть тысячи классов в вашем пути к классам, только часть из которых когда-либо понадобится (rt.jar только 48MB в наше время!).
Так что, даже если бы вы могли перечислить все классы, это заняло бы много времени и памяти.
Простой подход состоит в том, чтобы перечислить соответствующие классы в установочном файле (xml или любой другой, который вам подходит); если вы хотите сделать это автоматически, ограничьте себя одним JAR или одним каталогом классов.
источник
Google Reflection если вы хотите открыть интерфейсы.
Весна
ClassPathScanningCandidateComponentProvider
не открывает интерфейсы.источник
Google Reflections кажется намного быстрее, чем Spring. Нашел этот запрос функции, который устраняет эту разницу: http://www.opensaga.org/jira/browse/OS-738
Это причина использовать Reflections, так как время запуска моего приложения действительно важно во время разработки. Отражения, кажется, также очень просты в использовании для моего случая использования (найти все реализации интерфейса).
источник
Если вы ищете альтернативу отражениям, я бы рекомендовал Panda Utilities - AnnotationsScanner . Это сканер без гуавы (Гуава имеет ~ 3 МБ, Panda Utilities имеет ~ 200 КБ) сканер, основанный на исходном коде библиотеки отражений.
Он также предназначен для будущих поисков. Если вы хотите сканировать несколько раз включенные источники или даже предоставить API, который позволяет кому-то сканировать текущий путь к классу,
AnnotationsScannerProcess
кэширует все извлеченныеClassFiles
, так что это действительно быстро.Простой пример
AnnotationsScanner
использования:источник
Весна имеет то, что называется
AnnotatedTypeScanner
классом.Этот класс внутренне использует
Этот класс имеет код для фактического сканирования пути к классам ресурсов . Это делается с помощью метаданных класса, доступных во время выполнения.
Можно просто расширить этот класс или использовать тот же класс для сканирования. Ниже приведено определение конструктора.
источник