【问题标题】:How to work with classloader and annotations如何使用类加载器和注解
【发布时间】:2015-08-08 20:47:04
【问题描述】:

我正在尝试从方法中获取注释,但遇到了一些麻烦。我正在做的是使用 URLClassLoader 加载一个 jar 文件,然后我正在使用反射和 Method.getAnnotation 检查该 jar 中类中方法的注释。
我遇到的问题是 Method.getAnnotation 将返回始终返回 null,即使注释存在(我们可以使用 Method.getAnnotations 看到)。我已经在没有使用 URLClassLoader 加载的类上对相同的注释类型测试了相同的过程,它工作正常。
更深入的调查表明 instance.annotationType() 和 MyAnnotation.class 的规范名称是相同的。但是 instance.annotationType().equals(MyAnnotation.class) 返回 false。然而,实例本身是一个代理 (com.sun.proxy)。

有没有办法在没有大量反射的情况下获取注释和注释的字段?

instance.annotationType().getMethod("value").invoke(instance)

以上内容可以在该领域工作,并通过对规范名称的字符串比较迭代 Method.getAnnotations 的结果可以获得注释,但肯定有更好的方法吗?

还有教育价值,是什么原因造成的?我的猜测是,这是因为系统类加载器加载的注解的类与 URL 类加载器加载的注解的类在某种程度上不同。

【问题讨论】:

  • 我同意你的猜测。存在两种类型的 MyAnnotation。要解决此问题,请确保使用相同的类加载器加载带注释的类和注释。如果您的自定义类加载器使用当前的类加载器作为父类,也许会有所帮助。
  • @CoronA 自定义类加载器确实使用当前类加载器作为父类。我不知道如何确保它们使用相同的加载器加载,我需要更多关于 JVM 内部和这些类型事物的生命周期的知识。
  • 您可能可以访问您的自定义类加载器。您可以调用getAnnotation(customClassLoader.load("MyAnnotation"))(使用完整的类名)而不是调用getAnnotation(MyAnnotation.class)。确保在加载此类之前未引用 MyAnnotation。
  • 试过了,打字有问题。 load 需要一个 Class,但我不知道如何让 T 成为 MyAnnotation。
  • @kag0 如果您显示类加载器代码或它是如何创建的,那么有人可能会帮助修复父委托。否则,尝试使用Annotation.class.cast(customClassLoader.loadClass("MyAnnotation")) 安抚javac。

标签: java reflection annotations classloader proxy-classes


【解决方案1】:

一个hacky解决方案如下:

代替AccessibleObject.getAnnotation(Class annotationClass)使用

private static Annotation getAnnotation(AccessibleObject object, Class annotationClass){
    for(Annotation a : object.getAnnotations()){
        if(a.annotationType().getCanonicalName().equals(annotationClass.getCanonicalName()))
            return a;
    }
    return null;
}

代替 MyAnnotation.value() 使用

private static Object getAnnotationFieldWithReflection(Annotation annotation, String fieldName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    return annotation.annotationType().getMethod(fieldName).invoke(annotation);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多