不同classloader加载的class造成isAnnotationPresent失效
@ComponentClass
public class Home {
}
Class clazz = loader.loadClass("Home"); //loader 和现在运行的classLoader不是相同的。
flag = clazz.isAnnotationPresent(ComponentClass.class);//返回false
原因:
Class.clss
public boolean isAnnotationPresent(
Class<? extends Annotation> annotationClass) {
if (annotationClass == null)
throw new NullPointerException();
return getAnnotation(annotationClass) != null;
}
public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
if (annotationClass == null)
throw new NullPointerException();
initAnnotationsIfNecessary();
return (A) annotations.get(annotationClass);
}
private transient Map<Class, Annotation> annotations;
而不同的ClassLoader 加载的ComponentClass不是同一个对象,所以用Class作为id不合适,应该使用String。
解决办法:
ComponentClass.class也使用loader加载这样才能保证一致性。
banq详细的解答了这个问题:
http://www.jdon.com/jive/article.jsp?forum=91&thread=15456
Classloader存在下面问题:
在一个JVM中可能存在多个ClassLoader,每个ClassLoader拥有自己的
NameSpace。一个ClassLoader只能拥有一个class对象类型的实例,但是不同的ClassLoader可能拥有相同的class对象
实例,这时可能产生致命的问题。如ClassLoaderA,装载了类A的类型实例A1,而ClassLoaderB,也装载了类A的对象实例A2。逻辑
上讲A1=A2,但是由于A1和A2来自于不同的ClassLoader,它们实际上是完全不同的,如果A中定义了一个静态变量c,则c在不同的
ClassLoader中的值是不同的。
Thread{
ClassLoader cl = Thread.currentThread().getContextClassLoader();
URL[] urls = ...
ClassLoader ncl = new URLClassLoader(urls, cl);//构造新的
Thread.currentThread().setContextClassLoader(ncl);
do do do do;
Thread.currentThread().setContextClassLoader(cl);//执行完恢复
}