Alat untuk menemukan kelas beranotasi di Jawa

Artikel ini menyediakan ikhtisar singkat dari tiga alat untuk menemukan kelas beranotasi dalam proyek java.


gambar


Melatih kucing
@Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation {} @MyAnnotation public class Bar {} @MyAnnotation public class Foo {} 

Musim semi


Di Musim Semi, ClassPathScanningCandidateComponentProvider berfungsi untuk tujuan ini.


Fitur: merangkak ke ClassPath, mencari kelas yang memenuhi kondisi yang diberikan

Fitur tambahan

memiliki banyak filter lain (untuk tipe, metode, dll.)


Contoh


 @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")); } 

Refleksi


Fitur: merangkak ke ClassPath, mencari kelas yang memenuhi kondisi yang diberikan

Fitur tambahan
  • dapatkan semua subtipe dari beberapa tipe
  • dapatkan semua jenis / anggota beranotasi dengan beberapa anotasi
  • dapatkan semua sumber daya yang cocok dengan ekspresi reguler
  • dapatkan semua metode dengan tanda tangan spesifik termasuk parameter, anotasi parameter, dan tipe pengembalian

ketergantungan
 <dependency> <groupId>org.reflections</groupId> <artifactId>reflections</artifactId> <version>0.9.11</version> </dependency> 

Contoh


 @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")); } 

kelasindeks


Fitur: JANGAN masuk ke ClassPath, sebaliknya, kelas diindeks pada waktu kompilasi

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

Melatih kucing
 @IndexMyAnnotated public @interface IndexerAnnotation {} @IndexerMyAnnotation public class Bar {} @IndexerMyAnnotation public class Foo {} 

Contoh


 @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")); } 

Jmh


 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 

Kesimpulan


Seperti yang Anda lihat, pengindeks adalah alat yang paling produktif, namun, penjelasan yang digunakan untuk mencari harus memiliki stereotip @IndexAnnotated.


Dua alat lainnya bekerja jauh lebih lambat, tetapi untuk pekerjaan mereka tidak diperlukan perdukunan dengan kode. Kerugiannya sepenuhnya diratakan jika pencarian hanya diperlukan pada awal aplikasi

Source: https://habr.com/ru/post/id424511/


All Articles