<%@ page contentType="text/html; charset=gb2312"%> Java编程极限考验:ClassLoader类装载策略
网站公告:   ◆北天JAVA技术网热情为java爱好者服务,本网内容包括JAVA(JSP、servlet、EJB、webservice、j2ee、javabean、应用服务器、JavaScript),数据库(MYSQL、SQL Server、Sybase、Oracle、DB2、数据库综合知识),设计研究(设计模式、Struts、Spring、Hibernate、设计框架、设计综合知识),WEB2.0新技术(主要介绍AJAX),以及各种技术的入门、实例、例子等等,欢迎各位多来坐坐!◆  诚邀各位JAVA爱好者加盟!◆  本网站内容丰富,更新快,保证每周20篇以上!  
加入收藏
设为首页
联系站长
承接项目
  相关资源:网站首页 | 免费培训学院 | 技术论坛 | JAVA聊天室 | 作家专栏 | 开发工具 | 认证考试 | 会员俱乐部
  JAVA技术初学者园地 | jsp与servlet | javascript | Java源代码 | EJB | web service | 应用服务器 | JAVA综合知识
  设计研究设计模式 | 设计框架 | Struts | Spring | Hibernate | 开源项目 | 面向对象设计 | 设计综合知识
  数 据 库MYSQL | SQL Server | Sybase | Oracle | DB2 | Informix | Access | 数据库综合知识
  其他资源:AJAX新技术 | 网站开发 | ERP软件 | OA办公软件 | 商业智能BI | 开发综合知识 | 承接项目 | 项目试用

 
 
Java编程极限考验:ClassLoader类装载策略
     发布者: 发布时间:2006-07-25
个人认为,Java编程中极限考验是Classloader机制的掌握和灵活运用,特别是在复杂的系统,如存在动态类装载,Reflect,EJB,AOP等环境。

CLass.forName()
和Thread.currentThread().getContextClassLoader())
是否一样?

在很多文章中,都认为两者是一致的,如Java研究组织中一篇文章,被我从google搜索到的:
http://www.javaresearch.org/article/showarticle.jsp?column=31&thread=10178
文中说"这个方法可以用Class.forName()代替",在一般简单情况是可以替代,但实际上有时候是不能替代的。

Classloader存在下面问题:
在一个JVM中可能存在多个ClassLoader,每个ClassLoader拥有自己的NameSpace。一个ClassLoader只能拥有一个class对象类型的实例,但是不同的ClassLoader可能拥有相同的class对象实例,这时可能产生致命的问题。如ClassLoaderA,装载了类A的类型实例A1,而ClassLoaderB,也装载了类A的对象实例A2。逻辑上讲A1=A2,但是由于A1和A2来自于不同的ClassLoader,它们实际上是完全不同的,如果A中定义了一个静态变量c,则c在不同的ClassLoader中的值是不同的。

因此,研究JBoss的ClassLoader策略,对于更好地实现EJB组件拼装是用好处的,因为,一个项目中可能要用其他项目的EJB组件,如何实现运行时EJB组件共享,如何实现EJB组件打包是很重要的。


为了说明ClassLoader对于复杂架构是至重关键,列举开源Portal产品Exo中ServivesManager类内容。

该类是Exo利用PicoCOntainer实现功能性Service JavaBeans初始化,在将那些Service性质的JavaBeans加载到pico中时,需要使用到Classloader,
Exo专门设立一个ServiceContext类:




public class ServiceContext { private ClassLoader cl; //包含Classloader信息 private Services services; public ServiceContext(ClassLoader cl, Services services) { this.cl = cl; this.services = services; } public ClassLoader getCl() { return cl; } public Services getServices() { return services; }}


在ServicesManager中,有:
private ClassLoader updatedClassLoader;

它的初始值是:
Thread.currentThread().getContextClassLoader();

如果,这里写Class.forName 那么简单,那么你头疼去吧。

但是这样不够:
在addService方法中,根据加入的不同ServiceContext实现类装载:



public void addService(ServiceContext context) { Services servicesToAdd = context.getServices(); String name = servicesToAdd.getName(); URLClassLoader cl = null; if(context.getCl() instanceof URLClassLoader) { cl = (URLClassLoader) context.getCl(); } else { cl = URLClassLoader.newInstance(new URL[]{}, context.getCl()); } updatedClassLoader = new URLClassLoader(cl.getURLs(), updatedClassLoader); synchronized (servicesContext) { servicesContext.put(name, context); reloadContainer(); } }


其实向Picocontainer中加入一个服务很简单,上述方法的主要代码是处理Classloader,考虑到Classloader有嵌套关系,上述代码小心使用这个Service服务的父Classloader,使用父Classloader装载服务Service。
(转载文章请保留出处:北天JAVA技术网(www.java114.com))
 
更多精彩文章:
Java项目资源布局方案
基于JAVA技术的搜索引擎的研究与实现
全面挖掘Java Excel API 使用方法
[Java]基本的学习实例
企业JavaBean(EJB) 3.0 全新体验
Java Web Framework综述
 
        
标 题:   
内 容:   
 
                                  
 
免责声明:该文章由网友发表,如果对您造成侵权,请联系站长

首页 - 承接项目 - 网站地图 - 联系我们 -
版权所有北天JAVA技术工作室 ICP证号:粤ICP备06079815号