Java - register all classes annotated with @MyAnnotation

I have an @MyAnnotation annotation and I can annotate any type (class) with it. Then I have a class called AnnotatedClassRegister , and I would like it to register all classes annotated with @MyAnnotation , so I can access them later. And I would like to register these classes automatically after creating AnnotatedClassRegister , if possible, and, most importantly, before creating annotated classes.

I have AspectJ and Guice at my disposal. The only solution I have encountered so far is to use Guice to insert a single-screen instance of AnnotatedClassRegister into an aspect that searches for all classes annotated with @MyAnnotation , and it adds the code needed to register such a class in its constructor, The disadvantage of this The solution is that I need to instantiate each annotated class so that the code added by AOP actually runs, so I cannot use the lazy instantiation of these classes.

A simplified pseudo-code example of my solution:

 // This is the class where annotated types are registered public class AnnotatedClassRegister { public void registerClass(Class<?> clz) { ... } } // This is the aspect which adds registration code to constructors of annotated // classes public aspect AutomaticRegistrationAspect { @Inject AnnotatedClassRegister register; pointcutWhichPicksConstructorsOfAnnotatedClasses(Object annotatedType) : execution(/* Pointcut definition */) && args(this) after(Object annotatedType) : pointcutWhichPicksConstructorsOfAnnotatedClasses(annotatedType) { // registering the class of object whose constructor was picked // by the pointcut register.registerClass(annotatedType.getClass()) } } 

What approach should be used to solve this problem? Is there an easy way to get all such annotated classes in the class path through reflection so that I don't need to use AOP at all? Or any other solution?

Any ideas are greatly appreciated, thanks!

+6
source share
4 answers

Maybe:

  • Get all the way to class. Parse System.getProperties().getProperty("java.class.path", null) to get all the paths.

  • Use ClassLoader.getResources(path) to get all resources and check classes: http://snippets.dzone.com/posts/show/4831

+7
source

This is not just that much sure, but I would do it using Pure Java:

  • Get Jar Application Location From Class Path
  • Create a JarFile object with this location, iterate over the elements
  • for each entry ending with .class , execute Class.forName() to get a class object
  • read the annotation by reflection. If present, save the class in the list or set

Aspects will not help you, because aspects only work on really executed code.

But annotation processing can be an option, create a Processor that writes all annotated classes and creates a class that provides a list of these classes

+4
source

Well, if your AnnotatedClassRegister.registerClass() does not need to be called right away when AnnotatedClassRegister , but it can wait for the class to be created first, then I would consider using the Guice TypeListener registered with Matcher , which checks if the class was annotated with using @MyAnnotation .

Thus, you do not need to search for all these classes, they will be registered immediately before use. Note that this will only work for classes that are created using Guice.

0
source

I would use pointcut staticinitialization() in AspectJ and change the classes in your register when they are loaded, for example:

 after() : staticinitialization(@MyAnnotation *) { register.registerClass(thisJoinPointStaticPart.getSignature().getDeclaringType()); } 

A piece of cake, very simple and elegant.

0
source

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


All Articles