不同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);//執行完恢復
}