Есть ли простой способ получить список файлов 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:
Метод ЗАМЕТКА: уменьшен для удобства чтения
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 для получения ресурсов класса в пакете, а затем проверка метаданных этих классов - нормальный способ.
Я бы посмотрел, как другие библиотеки делают то же самое, например, проверил, как Spring сканирует пакеты на предмет определенных аннотаций.