【问题标题】:How can I find all classes on the classpath that have a specific method annotation?如何找到类路径上具有特定方法注释的所有类?
【发布时间】:2010-10-14 03:31:28
【问题描述】:

我想在 Java 中实现一种基于注解的初始化机制。具体来说,我定义了一个注释:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Initialization {

/**
 * If the eager initialization flag is set to <code>true</code> then the
 * initialized class will be initialized the first time it is created.
 * Otherwise, it will be initialized the first time it is used.
 * 
 * @return <code>true</code> if the initialization method should be called
 *         eagerly
 */
boolean eager() default false;

}

另外,我还有一个界面:

public interface SomeKindOfBasicInterface {}

我想在我的类路径中找到 SomeKindOfBasicInterface 类的每个实现,该类在方法上有 @Initialization 注释。我正在查看 Spring 的 MetaDataReader 工具,这看起来是在执行此操作时推迟加载其他 SomeKindOfBasicInterface 实现的最佳方式......但我不确定如何像我一样进行搜索描述。有什么建议吗?

【问题讨论】:

标签: java spring annotations


【解决方案1】:

您可以使用Reflections,这是一个Java 运行时元数据分析工具。我已经使用它来获取给定类型的所有子类型,但它也可以处理您的情况。

【讨论】:

  • 我强烈建议不要使用反射或从根本上不使用类加载器,如果时间/空间效率是遥不可及的问题。您的类路径中可能有大量类,并且所有这些加载的类现在都在 permgen 中。使用 ASM(或字节码库)之类的东西并简单地读取 byte[]s,使用 ASM 库获取有关类的信息,例如“它是用 x 注释的吗?”然后才真正加载该类(如果您碰巧需要该类)。
  • @alphazero: Reflections 实际上并不像这样使用 java.lang.reflect。与您描述的方法类似,它使用 Javassist 来读取类元数据,以避免实际加载类。
  • @Nicholas 我认为这是特定于 JVM 实现的。没有仔细看规格。 (最近)所以如果这确实是规范的(“使用 javassist”)会很感激这个链接!
  • 注意Reflections的链接。它是一个库,而不是 JVM 内置的。查看链接。
【解决方案2】:

我基本上会创建一个BeanPostProcessor 实现,可能基于CommonAnnotationBeanPostProcessor。然后我会设置component-scan,它会扫描类路径并获取所有符合您的规范的bean。初始化 bean 后,您的后处理器将运行。

我知道我假设您正在寻找豆子。如果不是这种情况,您可能必须自己扫描类路径。

【讨论】:

    【解决方案3】:

    你可以使用javassist在你的类中找到注释,甚至在你加载它们之前,但是你需要直接读取.class文件,这可能意味着你自己打开一个JAR等等。你还需要知道在哪里寻找课程。您不能只向运行时询问您的 BasicInterface 的所有子类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-26
      • 2012-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多