3

我正在开发一个传递消息的小型应用程序,它们是 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 的帮助下,我也花了非常非常长的时间来涉足抽象层次并获得一些大胆的代码,向我展示它如何扫描类中的类webapp 搜索带注释的类以注册@WebServlet、@WebListener 等。更令人反感的是,我只能在测试类中真正看到对这些注释的引用。

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

所以我想归结为:

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

注意:扫描类路径以查找具有自定义注释的类非常棒,但如果可能的话,我希望使用标准 Java 7 来完成。

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

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

4

1 回答 1

2

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

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

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

于 2013-11-10T18:21:56.980 回答