我正在尝试动态加载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