动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ Java教程 ]的信息

本月文章推荐
.调试器--jdb.exe.
.JAVA 和.NET在安全功能的比较.
.用JAVA访问共享文件系统.
.全面挖掘JavaExcelAPI使用方法.
.J2EE应用开发中与Oracle数据库的.
.Java做一个最简单的Socket通话程.
.java的关键知识点.
.Java Q&A: 使用Factory Method模.
.Struts+Spring+Hibernate实现上传.
.Java虚拟机(JVM)对象创建浅析.
.JScript 的运算符.
.Java图像处理技巧四则.
.使用Eclipse SWT控件开发WE.
.Tomcat5集群性能测试!.
.开源工作流编辑器 JaWE&nbs.
.数据库中数据项变化不定,如何设.
.利用Jmail发带附件的邮件.
.配置JDK / JAVA.
.分享关于Java语言中的函数编程.
.巧用JAVASCRIPT代码限制文本字节.

一个简单的自定义ClassLoader的实现

发表日期:2008-1-5 |


 


很多时候人们会使用一些自定义的ClassLoader ,而不是使用系统的Class Loader。大多数时候人们这样做的原因是,他们在编译时无法预知运行时会需要那些Class。非凡是在那些appserver中,比如tomcat,Avalon-phonix,Jboss中。或是程序提供一些plug-in的功能,用户可以在程序编译好之后再添加自己的功能,比如ant, jxta-shell等。定制一个ClassLoader很简单,一般只需要理解很少的几个方法就可以完成。
一个最简单的自定义的ClassLoader从ClassLoader类继续而来。这里我们要做一个可以在运行时指定路径,加载这个路径下的class的ClassLoader。
通常我们使用ClassLoader.loadClass(String):Class方法,通过给出一个类名,就会得到一个相应的Class实例。因此只要小小的改动这个方法,就可以实现我们的愿望了。
源码:

protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { // First, check if the class has already been loaded Class c = findLoadedClass(name); if (c == null) { try { if (parent != null) { c = parent.loadClass(name, false); }else{ c = findBootstrapClass0(name); } }catch(ClassNotFoundException e){ // If still not found, then call findClass in order // to find the class. c = findClass(name); } } if (resolve) { resolveClass(c); } return c;}

Source from ClassLoader.Java

First,check JavaAPI doc:上面指出了缺省的loadClass方法所做的几个步骤。
1. 调用findLoadedClass(String):Class 检查一下这个class是否已经被加载过了,由于JVM 规范规定ClassLoader可以cache它所加载的Class,因此假如一个class已经被加载过的话,直接从cache中获取即可。
2. 调用它的parent 的loadClass()方法,假如parent为空,这使用JVM内部的class loader(即闻名的bootstrap classloader)。
3. 假如上面两步都没有找到,调用findClass(String)方法来查找并加载这个class。
后面还有一句话,在Java 1.2版本以后,鼓励用户通过继续findClass(String)方法实现自己的class loader而不是继续loadClass(String)方法。
既然如此,那么我们就先这么做:)

public class AnotherClassLoader extends ClassLoader { private String baseDir;private static final Logger LOG = Logger.getLogger(AnotherClassLoader.class); public AnotherClassLoader (ClassLoader parent, String baseDir) { super(parent); this.baseDir = baseDir; } protected Class findClass(String name) throws ClassNotFoundException { LOG.debug("findClass " + name); byte[] bytes = loadClassBytes(name); Class theClass = defineClass(name, bytes, 0, bytes.length);//A if (theClass == null) throw new ClassFormatError(); return theClass; } private byte[] loadClassBytes(String className) throws ClassNotFoundException { try { String classFile = getClassFile(className); FileInputStream fis = new FileInputStream(classFile); FileChannel fileC = fis.getChannel(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); WritableByteChannel outC = Channels.newChannel(baos); ByteBuffer buffer = ByteBuffer.allocateDirect(1024); while (true) { int i = fileC.read(buffer); if (i == 0 i == -1) { break; } buffer.flip(); outC.write(buffer); buffer.clear(); } fis.close(); return baos.toByteArray(); } catch (IOException fnfe) { throw new ClassNotFoundException(className); } } private String getClassFile(String name) { StringBuffer sb = new StringBuffer(baseDir); name = name.replace('.', File.separatorChar) + ".class"; sb.append(File.separator + name); return sb.toString(); }}

[i]Ps:这里使用了一些JDK1.4的nio的代码:)[/i]
很简单的代码,要害的地方就在A处,我们使用了defineClass方法,目的在于把从class文件中得到的二进制数组转换为相应的Class实例。defineClass是一个native的方法,它替我们识别class文件格式,分析读取相应的数据结构,并生成一个class实例。

还没完呢,我们只是找到了发布在某个目录下的class,还有资源呢。我们有时会用Class.getResource():URL来获取相应的资源文件。假如仅仅使用上面的ClassLoader是找不到这个资源的,相应的返回值为null。

同样我们看一下原来的ClassLoader内部的结构。

public java.net.URL getResource(String name) { name = resolveName(name); ClassLoader cl = getClassLoader0();//这里 if (cl==null) { // A system class. return ClassLoader.getSystemResource(name); } return cl.getResource(name);}


原来是使用加载这个class的那个classLoader获取得资源。


public URL getResource(String name) { URL url; if (parent != null) { url = parent.getResource(name); } else { url = getBootstrapResource(name); } if (url == null) { url = findResource(name);//这里 } return url;}




这样看来只要继续findResource(String)方法就可以了。修改以下我们的代码:


//新增的一个findResource方法protected URL findResource(String name) { LOG.debug("findResource " + name); try { URL url = super.findResource(name); if (url != null) return url; url = new URL("file:///" + converName(name)); //简化处理,所有资源从文件系统中获取 return url; } catch (MalformedURLException mue) { LOG.error("findResource", mue); return null; }}private String converName(String name) { StringBuffer sb = new StringBuffer(baseDir); name = name.replace('.', File.separatorChar); sb.append(File.separator + name); return sb.toString();}


好了,到这里一个简单的自定义的ClassLoader就做好了,你可以添加其他的调料(比如安全检查,修改class文件等),以满足你自己的口味:)


上一篇:漫谈Java中的中文问题 人气:408
下一篇:ClassLoader介绍 人气:423
浏览全部Java的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-10-10 企业网站智能管理系统(TZIMS) v6
2008-10-10 拓文asp.net网站内容管理系统 v6
2008-10-10 动网论坛PHP版 v2.0++ Build 081
2008-10-10 免费时代CMS v5.0
2008-10-10 wodig第四季中文DIGG社区 v4.1 b
2008-10-10 老Y文章管理系统 v2.2 bulid 081
2008-10-10 魔法盒动感相册 ASP+SQL版 v2.0
2008-10-10 Asoft签到管理系统 v3.0 Pack1
2008-10-10 哥特人音乐网潮流留言本 v1.1
2008-10-11 iLighter打火机 v1.0 破解版
2008-10-11 iNetwork网速测试 v1.0.3破解版
2008-10-11 I-Private绝对隐私 v1.0 破解版
2008-10-11 iQuranPro可兰经专业版 v2.1 破解
2008-10-11 iRecorder录音机 v1.2汉化破解版
2008-10-11 iPrayPro宗教祈祷软件 v2.1 破解
2008-10-11 Garf记忆锻炼 v1.0 破解版
2008-10-11 Hebrew希伯来语字典 v2.0 破解版
2008-10-11 iPrayPro宗教祈祷软件 v2.0 破解
  发表评论
姓 名: 验证码:
内 容:
站长工具:网站收录查询 | Google PR查询 | ALEXA排名查询 | CSS在线编辑器 | 广告代码 | js/vbs加密 | md5加密 | 进制转换 | UTF-8 转换工具 | Html转换js | Html转换asp | Html转换php | Html转换perl
实用工具:汉字翻译拼音 | 拼音字典 | 符号对照表 | 个税计算 | 实时汇率查询换算 | 经典小工具 | 汉字简繁转换 | 普通单位换算 | 公制单位换算 | 生辰老黄历 | 国内电话区号 | 国家代码与域名缩写 | 文字加密解密 | 健康查询 | 万年历 | 汉字横竖排版 | 手机号码查询 | 计算器 | ip搜索
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号
ホームページ制作 不動産検索システム 求人情報
防水工事·改修工事 フットサル大会 探偵
SEO対策 中国語教室 ホームページ作成