Сканирование аннотаций Java во время выполнения - PullRequest
229 голосов
/ 03 ноября 2008

Каков наилучший способ поиска аннотированного класса по всему классу?

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

Знаете ли вы библиотеку или средство Java для этого?

Edit: я думаю о чем-то вроде новой функциональности для веб-сервисов Java EE 5 или EJB. Вы аннотируете свой класс с помощью @WebService или @EJB, и система находит эти классы во время загрузки, чтобы они были доступны удаленно.

Ответы [ 17 ]

2 голосов
/ 03 ноября 2008

Я не уверен, поможет ли это вам или нет, но вы можете заглянуть в проект Apache Commons-Discovery.

проект открытия

2 голосов
/ 03 ноября 2008

Classloader API не имеет метода «перечисления», потому что загрузка классов - это действие «по требованию» - у вас обычно есть тысячи классов в вашем пути к классам, только часть из которых когда-либо понадобится ( Один rt.jar в настоящее время составляет 48 МБ!).

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

Простой подход состоит в том, чтобы перечислить соответствующие классы в установочном файле (xml или любой другой, который вам подходит); если вы хотите сделать это автоматически, ограничьте себя одним JAR или одним каталогом классов.

1 голос
/ 29 декабря 2018

Google Reflection , если вы также хотите открыть интерфейсы.

Spring ClassPathScanningCandidateComponentProvider не обнаруживает интерфейсы.

1 голос
/ 14 августа 2018

Если вы ищете альтернативу отражениям Я бы хотел порекомендовать Panda Utilities - AnnotationsScanner . Это сканер без гуавы (у Гуавы ~ 3MB, у Panda Utilities ~ 200kb) сканер, основанный на исходном коде библиотеки отражений.

Он также предназначен для будущих поисков. Если вы хотите сканировать несколько раз включенные источники или даже предоставить API, который позволяет кому-либо сканировать текущий путь к классу, AnnotationsScannerProcess кэширует все извлеченные ClassFiles, так что это действительно быстро.

Простой пример использования AnnotationsScanner:

AnnotationsScanner scanner = AnnotationsScanner.createScanner()
        .includeSources(ExampleApplication.class)
        .build();

AnnotationsScannerProcess process = scanner.createWorker()
        .addDefaultProjectFilters("net.dzikoysk")
        .fetch();

Set<Class<?>> classes = process.createSelector()
        .selectTypesAnnotatedWith(AnnotationTest.class);
1 голос
/ 14 июля 2012

Google Reflections , кажется, намного быстрее, чем Spring. Нашел этот запрос функции, который устраняет эту разницу: http://www.opensaga.org/jira/browse/OS-738

Это причина для использования Reflections, так как время запуска моего приложения действительно важно во время разработки. Отражения, кажется, также очень просты в использовании для моего случая использования (найти все реализации интерфейса).

0 голосов
/ 28 мая 2019

Spring имеет класс, называемый AnnotatedTypeScanner.
Этот класс внутренне использует

ClassPathScanningCandidateComponentProvider

Этот класс имеет код для фактического сканирования ресурсов classpath . Это делается с помощью метаданных класса, доступных во время выполнения.

Можно просто расширить этот класс или использовать тот же класс для сканирования. Ниже приведено определение конструктора.

/**
     * Creates a new {@link AnnotatedTypeScanner} for the given annotation types.
     * 
     * @param considerInterfaces whether to consider interfaces as well.
     * @param annotationTypes the annotations to scan for.
     */
    public AnnotatedTypeScanner(boolean considerInterfaces, Class<? extends Annotation>... annotationTypes) {

        this.annotationTypess = Arrays.asList(annotationTypes);
        this.considerInterfaces = considerInterfaces;
    }
0 голосов
/ 12 сентября 2011

Если вам нужна библиотека Scala, используйте Sclasner: https://github.com/ngocdaothanh/sclasner

...