用于在Java中查找带注释的类的工具

本文简要概述了三种用于在Java项目中查找带注释的类的工具。


图片


训练猫
@Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation {} @MyAnnotation public class Bar {} @MyAnnotation public class Foo {} 

春天


在Spring中,ClassPathScanningCandidateComponentProvider用于此目的。


功能:爬到ClassPath中,查找满足给定条件的类

附加功能

还有许多其他过滤器(用于类型,方法等)


例子


 @Benchmark public void spring() { ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); scanner.addIncludeFilter(new AnnotationTypeFilter(MyAnnotation.class)); List<String> collect = scanner .findCandidateComponents("edu.pqdn.scanner") .stream() .map(BeanDefinition::getBeanClassName) .filter(Objects::nonNull) .collect(Collectors.toList()); assertEquals(collect.size(), 2); assertTrue(collect.contains("edu.pqdn.scanner.test.Bar")); assertTrue(collect.contains("edu.pqdn.scanner.test.Foo")); } 

感言


功能:爬到ClassPath中,查找满足给定条件的类

附加功能
  • 获取某种类型的所有子类型
  • 获取所有类型/成员并添加一些注释
  • 获取与正则表达式匹配的所有资源
  • 获取具有特定签名的所有方法,包括参数,参数注释和返回类型

依赖
 <dependency> <groupId>org.reflections</groupId> <artifactId>reflections</artifactId> <version>0.9.11</version> </dependency> 

例子


 @Benchmark public void reflection() { Reflections reflections = new Reflections("edu.pqdn.scanner"); Set<Class<?>> set = reflections.getTypesAnnotatedWith(MyAnnotation.class); List<String> collect = set.stream() .map(Class::getCanonicalName) .collect(Collectors.toList()); assertEquals(collect.size(), 2); assertTrue(collect.contains("edu.pqdn.scanner.test.Bar")); assertTrue(collect.contains("edu.pqdn.scanner.test.Foo")); } 

类索引


功能:不进入ClassPath,而是在编译时对类进行索引

依赖
 <dependency> <groupId>org.atteo.classindex</groupId> <artifactId>classindex</artifactId> <version>3.4</version> </dependency> 

训练猫
 @IndexMyAnnotated public @interface IndexerAnnotation {} @IndexerMyAnnotation public class Bar {} @IndexerMyAnnotation public class Foo {} 

例子


 @Benchmark public void indexer() { Iterable<Class<?>> iterable = ClassIndex.getAnnotated(IndexerMyAnnotation.class); List<String> list = StreamSupport.stream(iterable.spliterator(), false) .map(aClass -> aClass.getCanonicalName()) .collect(Collectors.toList()); assertEquals(list.size(), 2); assertTrue(list.contains("edu.pqdn.scanner.classindexer.test.Bar")); assertTrue(list.contains("edu.pqdn.scanner.classindexer.test.Foo")); } 

m


 Benchmark Mode Cnt Score Error Units ScannerBenchmark.indexer avgt 50 0,100 ? 0,001 ms/op ScannerBenchmark.reflection avgt 50 5,157 ? 0,047 ms/op ScannerBenchmark.spring avgt 50 4,706 ? 0,294 ms/op 

结论


如您所见,索引器是生产力最高的工具,但是,用于搜索的注释应具有@IndexAnnotated构造型。


其他两个工具的工作速度要慢得多,但是对于他们的工作,不需要使用代码的萨满主义。 如果仅在应用程序开始时才需要搜索,则完全消除了缺点

Source: https://habr.com/ru/post/zh-CN424511/


All Articles