java – URLClassLoader将Annotation加载为com.sun.$Proxy $27

我正在尝试动态加载
java类.基本思想是,jar包含在运行时动态加载的模块.我就是这样做的(我知道它很hacky,但是没有其他方法可以动态地将jar添加到已经存在的类加载器中):

Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class });
method.setAccessible(true);
method.invoke(moduleLoader, new Object[] { file.toURI().toURL() });
Class fooClass = moduleLoader.loadClass("com.coderunner.Foo");
Object foo = fooClass.newInstance();

每个模块都使用@Module注释进行注释.因此,为了获得有关模块的更多信息,我尝试获取注释.问题是foo上的注释是com.sun.$Proxy $27而不是com.coderunner.Module,因此我得到了一个

ClassCastException: Cannot cast com.sun.proxy.$Proxy42 (id=64) to com.coderunner.Module

我不得不说我有点困惑这里发生的事情.我想做什么?怎么样?

编辑:我也许应该提一下我在spring / spring-mvc和tomcat环境中尝试这个.

最佳答案 反射返回代理对象的事实不会阻止您收集有关注释及其值的信息.

getclass方法返回一个代理对象:

 log.info("annotation class:" + annotation.getClass());

输出:

 [INFO] annotation class:class com.sun.proxy.$Proxy16class 

输出与示例中的输出相同,但这没有问题.拥有方法(或字段)就足够了.另外一部分是调用注释方法.

public void analyseClass(Class myClass) {

    for (Method method: myClass.getMethods()) {
        System.out.println("aanotations :" + Arrays.toString(field.getAnnotations()));

        for (Annotation annotation : method.getAnnotations()) {

            log.info("annotation class:" + annotation.getClass());
            log.info("annotation class type:" + annotation.annotationType());

            Class<Annotation> type = (Class<Annotation>) annotation.annotationType();

            /* extract info only for a certain annotation */
            if(type.getName().equals(MyAnnotation.class.getName())) {

                 String annotationValue = 
                     (String) type.getMethod("MY_ANNOTATION_CERTAIN_METHOD_NAME").invoke(annotation);

                 log.info("annotationValue :" + annotationValue);
                 break;
            }
        }
    }

    //do the same for the fields of the class
    for (Field field : myClass.getFields()) {
         //...
    }

}  

为了解决这个问题,我使用了以下帖子:
How to get annotation class name, attribute values using reflection

点赞