java - 注释配置的框架(即 Tomcat、Hibernate)如何扫描类路径中的所有类以获取注释?

标签 java tomcat frameworks annotations

我正在开发一个传递消息的小型应用程序,消息是 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(或您上面提到的框架)的方法很糟糕,您会怎么做?
  • 有没有更好的方法来整体构建这个?

备注:Scan the classpath for classes with custom annotation很棒,但如果可能的话,我很乐意使用标准 Java 7 来完成。

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

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

最佳答案

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。

关于java - 注释配置的框架(即 Tomcat、Hibernate)如何扫描类路径中的所有类以获取注释?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19888802/

相关文章:

java - 请解释一下死锁的概念

swift - 在 Swift 中优雅地检查两个结构体实例是否不同

java - 在哪里可以找到类似于 Java 上的 XNA 的框架

java - JSR 296(Swing 应用程序框架)是否足够稳定可以使用?如果没有,小型 Swing 应用程序的其他选择是什么?

java - 从保存在CLOB上的文本中提取段落

java - 从字符串中删除尖括号 < 和 > : Java regex

java - 根据 Tomcat 上下文更改 servlet 映射

java - IntelliJ "Debug info unavailable"- 如何修复?

apache - 为什么在 sites-available 下更改默认文件也会更改 nginx 中 sites-enabled 下的默认文件?

java - visualvm - 无法检测到本地 Java 应用程序