科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道Java极限考验 ClassLoader类的装载策略

Java极限考验 ClassLoader类的装载策略

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

Java极限考验 ClassLoader类的装载策略

作者:dxaw 来源:赛迪网技术社区 2007年11月5日

关键字: 装载策略 java

  • 评论
  • 分享微博
  • 分享邮件

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。

查看本文来源
    • 评论
    • 分享微博
    • 分享邮件
    闂傚倷绶¢崣搴ㄥ窗閺囩偐鏋庨柕蹇嬪灪婵ジ鏌曡箛瀣偓鏍綖閿燂拷

    濠电姷顣介埀顒€鍟块埀顒€缍婇幃妯诲緞閹邦剛鐣洪梺闈浥堥弲婊勬叏濠婂牊鍋ㄦい鏍ㄧ〒閹藉啴鏌熼悜鈺傛珚鐎规洘宀稿畷鍫曞煛閸屾粍娈搁梻浣筋嚃閸ㄤ即宕㈤弽顐ュС闁挎稑瀚崰鍡樸亜閵堝懎濮┑鈽嗗亝濠㈡ê螞濡ゅ懏鍋傛繛鍡樻尭鐎氬鏌嶈閸撶喎顕i渚婄矗濞撴埃鍋撻柣娑欐崌閺屾稑鈹戦崨顕呮▊缂備焦顨呴惌鍌炵嵁鎼淬劌鐒垫い鎺戝鐎氬銇勯弽銊ф噥缂佽妫濋弻鐔碱敇瑜嶉悘鑼磼鏉堛劎绠為柡灞芥喘閺佹劙宕熼鐘虫緰闂佽崵濮抽梽宥夊垂閽樺)锝夊礋椤栨稑娈滈梺纭呮硾椤洟鍩€椤掆偓閿曪妇妲愰弮鍫濈闁绘劕寮Δ鍛厸闁割偒鍋勯悘锕傛煕鐎n偆澧紒鍌涘笧閹瑰嫰鎼圭憴鍕靛晥闂備礁鎼€氱兘宕归柆宥呯;鐎广儱顦伴崕宥夋煕閺囥劌澧ù鐘趁湁闁挎繂妫楅埢鏇㈡煃瑜滈崜姘跺蓟閵娧勵偨闁绘劕顕埢鏇㈡倵閿濆倹娅囨い蹇涗憾閺屾洟宕遍鐔奉伓

    重磅专题
    往期文章
    最新文章