تقدم هذه المقالة نظرة عامة موجزة على ثلاث أدوات للعثور على فئات مشروحة في مشروع جافا.

قطط تدريب@Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation {} @MyAnnotation public class Bar {} @MyAnnotation public class Foo {}
الربيع
في فصل الربيع ، يعمل 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")); }
جم
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.
تعمل الأداتان الأخريان بشكل أبطأ بكثير ، ولكن بالنسبة لعملهما ، لا حاجة إلى الشامانية مع الشفرة. يتم تسوية العيب تمامًا إذا كان البحث ضروريًا فقط في بداية التطبيق