jboss 类加载架构
jboss类加载机构中的核心组件是类装载器org.jboss.mx.loading.UnifiedClassLoader3(这里我们简称UCL).这个装载器是标准的java.net.URLClassLoader 的一个派生,所使用的共享池是org.jboss.mx.loading.UnifiedLoderRepository3.每个UCL都关联着一个共享池,而一个共享池通常被多个UCL使用.一个UCL可以有多个与之关联的URL来加载类和资源.
加载过程:
当UCL加载一个类时,首先检查与之相关联的共享池中的缓存,看这个类是否被加载过.当只有共享池的缓存中没有这个类时,UCL才会加载这个类.默认情况下,仅存在一个共享池,这个共享池为所有的UCL实例所共有.
下面是当UnifiedClassLoader3.loadClass(String,boolean)方法被调用时的执行步骤:
1 检查与UCL相关联的共享池缓存,如果缓存中存在改类,则返回
2 如果类不存在于缓存中,则看UnifiedClassLoader3是否能加载次类.实际上是调用了父类的URLClassLoader.loadClass(String,boolean)方法,测试这个类是否在类加载器相关的URL中,或者这个类对于父类装载器是否可见.如果通过这种方式找到了这个类,则将其放入共享池的缓存中,然后返回.
3 如果类没找到,则查询共享池中的所有UCL,看是否有能提供此类的UCL,共享池中将此类以包名UCL形式保存以供查询.当一个类被放入共享池后,即与一个包名的对应关系被建立,包名从与UCL相关联的URL中得来,同时,包名与UCL的映射关系被更新.这有利于迅速判断哪个UCL能够装载所指定的类. 共享池中的UCL按照被添加进来的顺序一次检查是否能装载指定的类,如果找到则返回;否则抛出java.lang.ClassNotFoundException.
完整的类加载模型
完整的加载类必须包含UnifiedClassLoader3的父加载器 以及用以范围管理的类加载器和其他特殊用途的类加载器,如下
1 System ClassLoaders
系统类装载器.指虚拟机主线程的上下文的类装载器或是加载JBoss服务器的应用程序线程(如果jboss服务器是嵌入在应用程序中)
2 ServerLoader
一个URLClassLoader,它委托系统类装载器进行装载,并包含以下用以启动的URL:
所有系统属性jboss.boot.library.list中列出的系统库路径,这些路径都是相对于jboss.lib.url所在的URL的相对路径.
JAXP的JAR包,根据Main函数入口指定的-j参数,可以是crimson.jar(默认)或xerces.jar
JBoss的JMX JAR包 jboss-jmx.xml以及GNU的regex JAR包
Oswego的并发处理类JAR包----concurrent.jar
所有通过命令行-L参数指定的JAR包
所有通过命令行-C参数指定的JAR包或目录.
3 Server
由org.jboss.system.server.Server接口实现创建的UCL对象集
4 All UnifierClassLoader
由部署器创建的的UCL.包括EAR,JAR,WAR,SAR,被部署扫描器发现的目录,以及在manifest.mf中所引用的JAR以及其中所包含的嵌套部署单元.
5 EJB DynClassLoader
URLClassLoader的子类,提供了通过http web方式进行rmi动态加载类功能.它指定一个空的URL数组,并委托TCL作为它的父加载器.如果WEB服务被配置为可以加载系统级的类,那么所有UnifierLoaderRepository3共享池中的类以及系统classpath路径下的类都可以通过http方式进行加载.
6 EJB ENCLoader
一个URLClassLoader.为EJB部署时的java:comp JNDI上下文提供一个唯一的上下文环境,它指定一个空的url[]数组,并且委托 EJB DynClassLoader作为父装载器
7 WEB ENCLoader
一个URLClassLoader.为WEB部署时的java:comp JNDI上下文提供一个唯一的上下文环境,它指定一个空的url[]数组,并且委托 TCL作为父装载器
8 WAR Loader
是一个与Servlet容器相关的类装载器,它委托WEB ENCLoader作为父装载器.其默认功能是从类装载器中转载类,然后装载WAR包的WEB-INF/classes目录下的类以及WEB-INF/lib下的jar包和资源.如果启用的Servlet2.3类加载模型,那么会先加载WEB-INF中的类和资源,然后再加载其父加载器中的类.