Java find class with annotations

Finds all classes within a package which are annotated with certain annotation. — Java java.lang.annotation

Finds all classes within a package which are annotated with certain annotation.

Demo Code

/*//w w w. j a v a 2 s . co m * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.io.FileInputStream; import java.io.IOException; import java.lang.annotation.Annotation; import java.io.File; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; public class Main< /** * Finds all classes within a package which are annotated with certain * annotation. * * @param annotation Annotation which we are looking for * @param Annotation class * @param packageName Package in which to search * @return The list of annotated classes */ public static extends Annotation> ListClass> getAnnotatedClasses( Class annotation, String packageName) < ArrayListClass> ret = new ArrayListClass>(); for (IteratorClass> it = getClassesIterator(packageName); it .hasNext();) < Class clazz = it.next(); if (clazz.getAnnotation(annotation) != null) < ret.add(clazz); >> return ret; > /** * @param packageName Package through which to iterate * @return Iterator through the classes of this jar file (if executed from * jar) or through the classes of org package (if .class file is * executed) */ public static IteratorClass> getClassesIterator(String packageName) < if (isExecutedFromJar()) < try < return new JarClassesIterator(packageName); > catch (IOException e) < throw new RuntimeException(e); > > else < return new GeneralClassesIterator(packageName); > > /** * @return Whether or not the code is executed from jar file */ private static boolean isExecutedFromJar() < return AnnotationUtils.class.getResource("AnnotationUtils.class") .getProtocol().equals("jar"); > >

Источник

Читайте также:  O reilly javascript jquery

Инструменты для поиска аннотированных классов в Java

В статье приведен небольшой обзор трех инструментов для поиска аннотированных классов в java проекте.

image

@Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation <> @MyAnnotation public class Bar <> @MyAnnotation public class Foo <>

Spring

В Spring для этих целей служит ClassPathScanningCandidateComponentProvider.

имеет множество других фильтров (для типа, для методов и т.д.)

Пример

@Benchmark public void spring() < ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); scanner.addIncludeFilter(new AnnotationTypeFilter(MyAnnotation.class)); Listcollect = 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")); >

Reflections

  • get all subtypes of some type
  • get all types/members annotated with some annotation
  • get all resources matching a regular expression
  • get all methods with specific signature including parameters, parameter annotations and return type
 org.reflections reflections 0.9.11 

Пример

@Benchmark public void reflection() < Reflections reflections = new Reflections("edu.pqdn.scanner"); Set> set = reflections.getTypesAnnotatedWith(MyAnnotation.class); List 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

 org.atteo.classindex classindex 3.4 
@IndexMyAnnotated public @interface IndexerAnnotation <> @IndexerMyAnnotation public class Bar <> @IndexerMyAnnotation public class Foo <>

Пример

@Benchmark public void indexer() < Iterable> iterable = ClassIndex.getAnnotated(IndexerMyAnnotation.class); List 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

Заключение

Как видно indexer самый производительный инструмент, однако, аннотации по которым производится поиск должны иметь стереотип @IndexAnnotated.

Другие два инструмента работают заметно медленнее, однако для их работы никакого шаманства с кодом производить не надо. Недостаток полностью нивелируется, если поиск необходим только на старте приложения

Источник

Scan the classpath in Java: how to find all annotated classes

In order to find all annotated classes by using the ClassHunter, we must add the following dependency to our pom.xml:

 org.burningwave core 12.62.7 

… And to use Burningwave Core as a Java module, add the following to your module-info.java :

requires org.burningwave.core;

Now we are able to find all annotated classes:

import java.util.Collection; import org.burningwave.core.assembler.ComponentContainer; import org.burningwave.core.assembler.ComponentSupplier; import org.burningwave.core.classes.ClassCriteria; import org.burningwave.core.classes.ClassHunter; import org.burningwave.core.classes.ConstructorCriteria; import org.burningwave.core.classes.FieldCriteria; import org.burningwave.core.classes.MethodCriteria; import org.burningwave.core.classes.SearchConfig; import org.burningwave.core.io.PathHelper; public class Finder < public Collection> find() < ComponentSupplier componentSupplier = ComponentContainer.getInstance(); PathHelper pathHelper = componentSupplier.getPathHelper(); ClassHunter classHunter = componentSupplier.getClassHunter(); SearchConfig searchConfig = SearchConfig.forPaths( //Here you can add all absolute path you want: //both folders, zip and jar will be recursively scanned. //For example you can add: "C:\\Users\\user\\.m2" //With the line below the search will be executed on runtime Classpaths pathHelper.getMainClassPaths() ).by( ClassCriteria.create().allThoseThatMatch((cls) -> < return cls.getAnnotations() != null && cls.getAnnotations().length >0; >).or().byMembers( MethodCriteria.withoutConsideringParentClasses().allThoseThatMatch((method) -> < return method.getAnnotations() != null && method.getAnnotations().length >0; >) ).or().byMembers( FieldCriteria.withoutConsideringParentClasses().allThoseThatMatch((field) -> < return field.getAnnotations() != null && field.getAnnotations().length >0; >) ).or().byMembers( ConstructorCriteria.withoutConsideringParentClasses().allThoseThatMatch((ctor) -> < return ctor.getAnnotations() != null && ctor.getAnnotations().length >0; >) ) ); try (ClassHunter.SearchResult searchResult = classHunter.findBy(searchConfig)) < //If you need all annotaded methods unconment this //searchResult.getMembersFlatMap().values(); return searchResult.getClasses(); >> >

Источник

Tools for searching annotated classes in Java

The article provides a small overview of the three tools for searching annotated classes in a java project.

image

@Retention(RetentionPolicy.RUNTIME) public@interface MyAnnotation <> @MyAnnotationpublicclass Bar <> @MyAnnotationpublicclass Foo <>

Spring

In Spring, ClassPathScanningCandidateComponentProvider serves for this purpose.

has many other filters (for type, for methods, etc.)

Example

@Benchmarkpublic void spring() < ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); scanner.addIncludeFilter(new AnnotationTypeFilter(MyAnnotation.class)); List 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")); >

Reflections

  • get all subtypes of some type
  • get all types / members annotated with some annotation
  • get all resources matching a regular expression
  • parameters, parameter returns and return type
dependency>groupId>org.reflectionsgroupId>artifactId>reflectionsartifactId>version>0.9.11version>dependency>

Example

@Benchmarkpublic void reflection() < Reflections reflections = new Reflections("edu.pqdn.scanner"); Set> set = reflections.getTypesAnnotatedWith(MyAnnotation.class); List 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.classindexgroupId>artifactId>classindexartifactId>version>3.4version>dependency>
@IndexMyAnnotatedpublic@interface IndexerAnnotation <> @IndexerMyAnnotationpublicclass Bar <> @IndexerMyAnnotationpublicclass Foo <>

Example

@Benchmarkpublic void indexer() < Iterable> iterable = ClassIndex.getAnnotated(IndexerMyAnnotation.class); List 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 ErrorUnits ScannerBenchmark.indexer avgt 500,100 ? 0,001 ms/op ScannerBenchmark.reflection avgt 505,157 ? 0,047 ms/op ScannerBenchmark.spring avgt 504,706 ? 0,294 ms/op

Conclusion

As you can see, the indexer is the most productive tool, however, the annotations for which the search is performed must have the stereotype @IndexAnnotated.

The other two tools are working much slower, but for their work no shamanism with code is needed. The disadvantage is completely leveled out if the search is needed only at the start of the application.

Источник

Оцените статью