classlaoder的问题

如果一个classloaderA加载了一个类A,而另一个被classloaderA加载的classloaderB也去加载类A,结果会是怎样的?按理说他们属于同一个命名空间,类A该不会被加载两次吧?我认为

1.首先classloader是一种tree-like的hierarchy的结构,这颗树的root是bootstrap classloader。当JVM启动后,系统往往会有三个或三个以上的Class Loader,也即:Bootstrap CL, Extension CL, System CL和User-defined CL。任何的CL都有一个parent CL(Bootstrap CL除外),从而所有的CL形成一颗自上而下的树,其中Bootstrap CL是这颗树的Root。
Bootstrap CL
└──Extension CL
└──System CL
└──User-defined CL.(classLoaderA)
└──User-defined CL.(classLoaderB)
2.Bootstrap CL负责载入core Java API class;Extension CL负责载入系统所安装的扩展Java函数库;System CL负责载入Classpath下的class。
3.Class的载入采用的是Delegation的模式,即:当系统向一个CL请求载入某一个class的时候,该CL把请求delegate给他的parent,如果parent返回相应的class,则CL返回parent所返回的class,如果parent返回null的话,则CL自己负责载入请求的class。(weblogic的classloader architecture有一个开关,当你disable那个开关的时候,child CL将不会delegate class-loading到他的parent,这是一个例外)
4.拿你说的那种情况来说,当client向classloaderB请求载入A的时候,classloaderB将会delegate这个请求给classloaderA,既然classloaderA可以返回A,那么classloaderB将会直接返回这个A给client。

在J2EE中,根据具体J2EE产品而定,JBoss 采取的类似weblogic方式,EJB的classloder和Web的classloader是两个,容器最新查找的是EJB的classloader,如果你的class被EJB的classloader加载了,Web层也需要使用这个class,那么将会报错,not found the class。

顺便再问一下,在代码中是如何给一个类设置指定的classloader的?

这个问题真是有点问题了!呵呵

试想想,小孩可以指定她的生母是A,而不是B吗?当一个孩子被生下来之后,她的生母是没有办法改变的。

同样的道理,一个class被load到JVM中以后,它肯定是被某一classloader载入的,它也没有办法改变它的生母,它有违现实逻辑。

另外,classloader architecture是java language security实现的一大基石,如果允许更改一个class所属的classloader将使得java security的大厦轰然倒塌。

兄弟,我指的是在第一次载入时如何使用指定的loader。就想EJB和WEB可以选择不同的loader那样。我想知道那是如何实现的。

兄弟,我指的是在第一次载入时如何使用指定的loader。就想EJB和WEB可以选择不同的loader那样。我想知道那是如何实现的。

兄弟,我指的是在第一次载入时如何使用指定的loader。就想EJB和WEB可以选择不同的loader那样。我想知道那是如何实现的。

兄弟,我指的是在第一次载入时如何使用指定的loader。就想EJB和WEB可以选择不同的loader那样。我想知道那是如何实现的。

当然可以 比如你又一个自己的ClassLoaderA,你要用它来装载ClassA,

ClassLoaderA cla = new ClassLoaderA();
Class cl = cla.loadClass("ClassA",true);
ClassA a = (ClassA)cl.newInstance();

可以参考Exo中有个ServicesManager类,这是使用PicoCOntainer的,同时也可自己指定ClassLoader

其实JVM CLASSLOADER加载CLASS是有层次的,首先是System ClassLoader
而后是 User ClassLoader,如果A在System ClassLoader中被装载
那么在User ClassLoader中就应该不会被第二次装载

我想知道一点,一个自定义的类可以完全明确指定自己的ClassLoader,只能用此指定的ClassLoader装载,而拒绝被其他的ClassLoader装载么?