9910

单飞

   :: 首页 :: 联系 :: 聚合  :: 管理
不同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);//执行完恢复
}
posted on 2006-12-20 20:35 单飞 阅读(389) 评论(0)  编辑  收藏 所属分类: java

只有注册用户登录后才能发表评论。


网站导航: