Получить список файлов Java в плагине Maven

Есть ли простой способ получить список файлов Java с определенной аннотацией в подключаемом модуле Maven? Я хочу запустить плагин как часть развертывания, чтобы вызвать другую службу, которая уведомляет обо всех классах, имеющих конкретную аннотацию.

Раньше я делал это во время выполнения, используя библиотеку Reflections, как показано ниже.

Reflections reflections = new Reflections(PACKAGE);
Set<Class<?>> checks = reflections.getTypesAnnotatedWith(FocusCheck.class);

Я думаю, это можно сделать, выполнив что-нибудь вроде

 @Parameter(defaultValue = "${project}", required = true, readonly = true)
MavenProject project;

тогда

List<String> compileSourceRoots = project.getCompileSourceRoots();

Затем мне нужно будет рекурсивно пройти по каждой папке в списке, найти файлы java и изучить их. Я подозреваю, что есть способ лучше.

Спасибо, Павел

Я бы посмотрел, как другие библиотеки делают то же самое, например, проверил, как Spring сканирует пакеты на предмет определенных аннотаций.

xtratic 06.11.2018 17:18

У вас есть ссылка, которая дала бы мне отправную точку, пожалуйста?

ceepan 06.11.2018 17:23
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
277
1

Ответы 1

Взгляните на некоторые из следующих исходных кодов Spring:

Метод ЗАМЕТКА: уменьшен для удобства чтения

org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider 
/**
 * Scan the class path for candidate components.
 * @param basePackage the package to check for annotated classes
 * @return a corresponding Set of autodetected bean definitions
 */
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
    Set<BeanDefinition> candidates = new LinkedHashSet<BeanDefinition>();
    try {
        String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                resolveBasePackage(basePackage) + "/" + this.resourcePattern;
        Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
        for (Resource resource : resources) {
            // check its metadata to see if it's what you want
        }
    }
    return candidates;
}

getResources() в конечном итоге вызывает следующий метод для получения ресурсов класса из пути к классам:

org.springframework.core.io.support.PathMatchingResourcePatternResolver
/**
 * Find all class location resources with the given path via the ClassLoader.
 * Called by {@link #findAllClassPathResources(String)}.
 * @param path the absolute path within the classpath (never a leading slash)
 * @return a mutable Set of matching Resource instances
 * @since 4.1.1
 */
protected Set<Resource> doFindAllClassPathResources(String path) throws IOException {
    Set<Resource> result = new LinkedHashSet<Resource>(16);
    ClassLoader cl = getClassLoader();
    Enumeration<URL> resourceUrls = (cl != null ? cl.getResources(path) : ClassLoader.getSystemResources(path));
    while (resourceUrls.hasMoreElements()) {
        URL url = resourceUrls.nextElement();
        result.add(convertClassLoaderURL(url));
    }
    if ("".equals(path)) {
        // The above result is likely to be incomplete, i.e. only containing file system references.
        // We need to have pointers to each of the jar files on the classpath as well...
        addAllClassLoaderJarRoots(cl, result);
    }
    return result;
}

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

Другие вопросы по теме