我正在开发一个传递消息的小型应用程序,消息是 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/