如何注释配置框架(即.Tomcat,Hibernate)扫描类路径中的所有类以查找注释



我正在开发一个传递消息的小应用程序,这些消息是POJO。我想构建一个可以处理的消息类型的注册表。我最初计划将它们粘贴在枚举类型中,如下所示。

public enum Message
{
    INIT( InitMessage.class, "init" ),
    REFRESH( RefreshMessage.class, "refresh" );
    private Message( Class<?> messageClass, String messageCode )
    // etc..
}

我不喜欢这种方法,因为我必须维护一个中心枚举类型来管理允许的类。我宁愿对 POJO 进行注释。

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

从Subversion中查看了Tomcat源代码,即使在IDE的帮助下,我也花了非常非常长的时间来完成抽象级别并获得一些大胆的代码,向我展示它如何在Web应用程序中扫描类,搜索带注释的类以注册@WebServlet,@WebListener, 等。更令人反感的是,我只能在测试类中看到对这些注释的引用。

我的问题是注释驱动的框架如何扫描注释?很难知道您希望扫描哪些类,在类加载器加载它们之前更是如此。我认为这种方法可能是查找所有以.class扩展名结尾的文件,加载它们并检查注释。但是,这种方法听起来很讨厌。

所以我想它归结为:

  • 雄猫如何找到带注释的类?(或您熟悉的任何其他框架)
  • 如果Tomcat(或你上面提到的框架)的方法很糟糕,你会怎么做?
  • 有没有更好的方法来构建它的整体?

注意:扫描类路径以查找带有自定义注释的类很棒,但如果可能的话,我很乐意使用标准 Java 7 来做到这一点。

更新:反射不合适。它有大量的依赖关系,更糟糕的是,它依赖于旧版本的库 - 特别是一个以每个版本弃用数十个功能并迅速发布而自豪的库。

我正在考虑遵循本指南并在可能的情况下使用 ASM:http://bill.burkecentral.com/2008/01/14/scanning-java-annotations-at-runtime/

Tomcat 使用缩减版本(因此仅存在 Tomcat 需要的位)和包重命名(因此如果 Web 应用程序也随 BCEL 一起提供,则不会发生冲突)版本的 Apache Commons BCEL 扫描注释。它查找每个.class文件,读取字节码并提取注释。

有关详细信息,您可以查看源代码。从此文件的第 1130 行开始:http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java?annotate=1537835

另一个用于做这种事情的流行库是 ASM。

最新更新