不同classloader加載的class造成isAnnotationPresent失效
@ComponentClass
public class Home {
}
Class clazz = loader.loadClass("Home");??? //loader 和現(xiàn)在運(yùn)行的classLoader不是相同的。
flag = clazz.isAnnotationPresent(ComponentClass.class);//返回false
原因:
Class.clss
?public boolean isAnnotationPresent(
??????? Class<? extends Annotation> annotationClass) {
??????? if (annotationClass == null)
??????????? throw new NullPointerException();
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不是同一個(gè)對(duì)象,所以用Class作為id不合適,應(yīng)該使用String。
解決辦法:
ComponentClass.class也使用loader加載這樣才能保證一致性。
banq詳細(xì)的解答了這個(gè)問題:
http://www.jdon.com/jive/article.jsp?forum=91&thread=15456
Classloader存在下面問題:
在一個(gè)JVM中可能存在多個(gè)ClassLoader,每個(gè)ClassLoader擁有自己的 NameSpace。一個(gè)ClassLoader只能擁有一個(gè)class對(duì)象類型的實(shí)例,但是不同的ClassLoader可能擁有相同的class對(duì)象 實(shí)例,這時(shí)可能產(chǎn)生致命的問題。如ClassLoaderA,裝載了類A的類型實(shí)例A1,而ClassLoaderB,也裝載了類A的對(duì)象實(shí)例A2。邏輯 上講A1=A2,但是由于A1和A2來(lái)自于不同的ClassLoader,它們實(shí)際上是完全不同的,如果A中定義了一個(gè)靜態(tài)變量c,則c在不同的 ClassLoader中的值是不同的。
Thread{
??? ??? ??? ClassLoader cl = Thread.currentThread().getContextClassLoader();
??? ??? ??? URL[] urls = ...
??? ??? ??? ClassLoader ncl = new URLClassLoader(urls, cl);//構(gòu)造新的
??? ??? ??? Thread.currentThread().setContextClassLoader(ncl);
??? ??? ??? do do do do;
??? ??? ??? Thread.currentThread().setContextClassLoader(cl);//執(zhí)行完恢復(fù)
}
@ComponentClass
public class Home {
}
Class clazz = loader.loadClass("Home");??? //loader 和現(xiàn)在運(yùn)行的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不是同一個(gè)對(duì)象,所以用Class作為id不合適,應(yīng)該使用String。
解決辦法:
ComponentClass.class也使用loader加載這樣才能保證一致性。
banq詳細(xì)的解答了這個(gè)問題:
http://www.jdon.com/jive/article.jsp?forum=91&thread=15456
Classloader存在下面問題:
在一個(gè)JVM中可能存在多個(gè)ClassLoader,每個(gè)ClassLoader擁有自己的 NameSpace。一個(gè)ClassLoader只能擁有一個(gè)class對(duì)象類型的實(shí)例,但是不同的ClassLoader可能擁有相同的class對(duì)象 實(shí)例,這時(shí)可能產(chǎn)生致命的問題。如ClassLoaderA,裝載了類A的類型實(shí)例A1,而ClassLoaderB,也裝載了類A的對(duì)象實(shí)例A2。邏輯 上講A1=A2,但是由于A1和A2來(lái)自于不同的ClassLoader,它們實(shí)際上是完全不同的,如果A中定義了一個(gè)靜態(tài)變量c,則c在不同的 ClassLoader中的值是不同的。
Thread{
??? ??? ??? ClassLoader cl = Thread.currentThread().getContextClassLoader();
??? ??? ??? URL[] urls = ...
??? ??? ??? ClassLoader ncl = new URLClassLoader(urls, cl);//構(gòu)造新的
??? ??? ??? Thread.currentThread().setContextClassLoader(ncl);
??? ??? ??? do do do do;
??? ??? ??? Thread.currentThread().setContextClassLoader(cl);//執(zhí)行完恢復(fù)
}