简体   繁体   中英

How do annotation-configured frameworks (ie. Tomcat, Hibernate) scan all classes in the classpath for annotations?

I'm developing a small application that passes messages around, which are POJOs. I'd like to construct a registry of the types of messages that can be handled. I originally planned to stick them in an enumerated type as follows.

public enum Message
{
    INIT( InitMessage.class, "init" ),
    REFRESH( RefreshMessage.class, "refresh" );

    private Message( Class<?> messageClass, String messageCode )
    // etc..
}

I don't like this approach, as I have to maintain a central enumerated type to manage the allowed classes. I'd prefer to instead annotate the POJOs.

@MessageDefinition( "init" )
public class InitMessage
{
    // .. some properties with appropriate getters and setters
}

I checked out the Tomcat source from Subversion, and even with the help of an IDE, it was taking me a very, very long time to wade through the levels of abstraction and get to some gutsy code showing me how it scans the classes in a webapp searching for annotated classes to register @WebServlet, @WebListener, etc. Even more off-putting was the fact that I could only really see references to those annotations in test classes.

My question is how do annotation driven frameworks scan for annotations? It's hard to know which classes you're hoping to scan, even moreso before they've been loaded by the classloader. I was thinking the approach might be to look for all files that end in a .class extension, load them and check for annotations. However, this approach sounds pretty nasty.

So I guess it boils down to:

  • how does Tomcat find annotated-classes? (or any other frameworks you're familiar with)
  • if Tomcat's (or the framework you mentioned above's) approach sucks, how would you do it?
  • is there a better way that I should architect this overall?

Note: Scan the classpath for classes with custom annotation is great, but I'd love to do it with standard Java 7 if possible.

Update: Reflections is not suitable. It has a tonne of dependencies, and to make things worse, it relies on old versions of libraries - in particular one that takes pride in deprecating dozens of features every release, and releasing rapidly.

I'm thinking about following this guide and using ASM if possible: http://bill.burkecentral.com/2008/01/14/scanning-java-annotations-at-runtime/

Tomcat scans for annotations using a cut-down (so only the bits Tomcat needs are present) and package renamed (so it doesn't clash if the web app ships with BCEL as well) version of Apache Commons BCEL. It looks for every .class file, reads the byte code and extracts the annotations.

For the details, you can look at the source code. Start at line 1130 of this file: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java?annotate=1537835

The other popular library for doing this sort of thing is ASM.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM