I have an annotation @MyAnnotation
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'd like to register these classes automatically upon creation of the AnnotatedClassRegister
if possible, and most importantly before the annotated classes are instantiated.
I have AspectJ and Guice at my disposal. The only solution I came up with so far is to use Guice to inject a singleton instance of the AnnotatedClassRegister
to an aspect, which searches for all classes annotated with @MyAnnotation
and it adds the code needed to register such class in its constructor. The downside of this solution is that I need to instantiate every annotated class in order for the code added by AOP to be actually run, therefore I cannot utilize lazy instantiation of these classes.
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 I use to address this problem? Is there any simple way to get all such annotated classes in classpath via reflection so I wouldn't need to use AOP at all? Or any other solution?
Any ideas are much appreciated, thanks!
It's possible:
Get all paths in a classpath. Parse System.getProperties().getProperty("java.class.path", null)
to get all paths.
Use ClassLoader.getResources(path)
to get all resources and check for classes: http://snippets.dzone.com/posts/show/4831
It isn't simple that much is sure, but I'd do it in a Pure Java way:
.class
do a Class.forName()
to get the Class objectAspects won't help you there, because aspects only work on code that's actually executed.
But annotation processing may be an Option, create a Processor that records all annotated classes and creates a class that provides a List of these classes
Well, if your AnnotatedClassRegister.registerClass()
doesn't have to be called immediately at AnnotatedClassRegister
creation time, but it could wait until a class is first instantiated, then I would consider using a Guice TypeListener
, registered with a Matcher
that checks if a class is annotated with @MyAnnotation
.
That way, you don't need to search for all those classes, they will be registered just before being used. Note that this will work only for classes that get instantiated by Guice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With