рдЬрд╛рд╡рд╛ рдореЗрдВ рдПрдиреЛрдЯреЗрдЯ рдХрдХреНрд╖рд╛рдПрдВ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдХрд░рдг

рдпрд╣ рд▓реЗрдЦ рдПрдХ рдЬрд╛рд╡рд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдПрдиреЛрдЯреЗрдЯ рдХрдХреНрд╖рд╛рдУрдВ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рддреАрди рдЯреВрд▓ рдХрд╛ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдЕрд╡рд▓реЛрдХрди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред


рдЫрд╡рд┐


рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдмрд┐рд▓реНрд▓рд┐рдпреЛрдВ
@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")); } 

classindex


рдлрд╝реАрдЪрд░: рдХреНрд▓рд╛рд╕ рдХреНрд▓рд╛рд╕ рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рддреЗ рд╣реИрдВ, рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдХрдХреНрд╖рд╛рдПрдВ рд╕рдВрдХрд▓рди рд╕рдордп рдкрд░ рдЕрдиреБрдХреНрд░рдорд┐рдд рдХреА рдЬрд╛рддреА рд╣реИрдВ

рдирд┐рд░реНрднрд░рддрд╛
 <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")); } 

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 

рдирд┐рд╖реНрдХрд░реНрд╖


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрдВрдбреЗрдХреНрд╕рд░ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдЙрддреНрдкрд╛рджрдХ рдЙрдкрдХрд░рдг рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЦреЛрдЬ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдПрдиреЛрдЯреЗрд╢рди рдореЗрдВ @IndexAnnotated рд╕реНрдЯреАрд░рд┐рдпреЛрдЯрд╛рдЗрдк рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред


рдЕрдиреНрдп рджреЛ рдЙрдкрдХрд░рдг рдмрд╣реБрдд рдзреАрдореА рдЧрддрд┐ рд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдирдХреЗ рдХрд╛рдо рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХреЗ рд╕рд╛рде рдХреЛрдИ рд╢рд░реНрдорд┐рдВрджрдЧреА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдиреБрдХрд╕рд╛рди рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдорддрд▓ рд╣реИ рдЕрдЧрд░ рдЦреЛрдЬ рдХреЗрд╡рд▓ рдЖрд╡реЗрджрди рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реИ

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


All Articles