来源:http://a123159521.iteye.com/blog/1095264

 package com.classloader.util;import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLStreamHandlerFactory;
import java.security.CodeSource;
import java.security.PermissionCollection;
import java.util.Enumeration;
import java.util.jar.Manifest;public class NetworkClassLoader extends URLClassLoader {String baseUrl;public String getBaseUrl() {return baseUrl;}public void setBaseUrl(String baseUrl) {this.baseUrl = baseUrl;}public NetworkClassLoader(){this(new URL[]{});}/*** URL 以'/'结尾的为目录*     否则为jar包*     未指定其父类加载器为系统类加载器* @param urls*/public NetworkClassLoader(URL[] urls) {super(urls);}/*** 同上,指定classLoader* @param urls* @param parent*/public NetworkClassLoader(URL[] urls, ClassLoader parent) {super(urls,parent);}/*** 同上,URL工厂处理器* @param urls* @param parent* @param factory*/public NetworkClassLoader(URL[] urls, ClassLoader parent,URLStreamHandlerFactory factory) {super(urls,parent,factory);}/*** [添加baseUrl]* @param url*/public void addURL(String url){URL uurl=null;try {uurl = new URL(baseUrl+url);} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();}addURL(uurl);}/*** 添加url[添加baseUrl]*/protected void addURL(URL url) {super.addURL(url);}/*** 返回urls*/public URL[] getURLs() {return super.getURLs();}/*** 查找类对象*   从以上的URLS中查找加载当前类对象[会打开所有的jars去查找指定的类]*   (可以通过调用findClass来得到以上URL加载包中的类)*/protected Class<?> findClass(String name) throws ClassNotFoundException {return super.findClass(name);}/*** defineClass SecureClassLoader定义为最终方法,不允许更改.* 在使用这个类对象前,必须先resolved(解析)*//*** 查找资源[自定义相对URL查找路径]*   从以上的URLS中查找当前名称的资源* 这个必须重写,因为是public 哈哈*/public URL findResource(String name) {URL url = null;try {url = new URL(baseUrl+name);} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();}return url;}/*** 查找资源列表[URL查找路径]*/public Enumeration<URL> findResources(String name) throws IOException {return super.findResources(name);}/*** 在当前的ClassLoader中,定义一个新的Package,Package的属性由Manifest指定.这个包的源文件*/protected Package definePackage(String name, Manifest man, URL url)throws IllegalArgumentException {return super.definePackage(name, man, url);}/*** 加载路径权限*/protected PermissionCollection getPermissions(CodeSource codesource) {return super.getPermissions(codesource);}
}

以下是用法:

 NetworkClassLoader loader = new NetworkClassLoader();loader.setBaseUrl("file:///F:\\框架\\maven\\app\\jms\\src\\main\\webapp\\modules\\");loader.addURL("App/lib/test.jar");loader.addURL("App/lib/test1.jar");loader.addURL("App/template/view.vm");loader.addURL("App/config.xml");

这里初始化了此类加载器所使用的类资源,配置文件等。 
以下是如何加载类资源:

Class clazz= loader.findClass("com.jvm.look.A");//加载类

以下是加载配置文件资源

URL uuu = loader.findResource("App/config.xml");

有一点需要注意的,这个类加载器还是双亲委托机制,比如有一个类"com.annotation.table.Test"在父类加载器中如果已经加载过了,那么如果这个类在test.jar中存在,那么不会重新定义加载,而使用父类加载器加载的类,有人问了,那我如何覆盖父类加载器中定义的类。 
可以进行如下操作:

Class clazz2= loader.findClass("com.annotation.table.Test");  

重新加载类,类的加载序列我在上一篇已经讲过了,不熟悉的可以看以上文章. 
可能有人会问了,如果每一个类都这样,那我不崩溃了,我需要把我加载的jar覆盖父类加载器中定义的所有类.

 /*** 覆盖父加载器中定义的类,使用当前类加载器加载资源,那么所有的类都在此加载器中执行.* 这样,所有URL中的类都通过此类加载器加载,也就是说URL中的类的定义类加载器就是当前类加载器.* 建议:尽量不要使用这种方式覆盖父加载器定义的类.[按一种约定双亲委托机制加载]* (如果重载了,那么尽量使用此loader加载类,这样所有逻辑都在此ClassLoader中运行,当然还有SDK还是从双亲加载)* 可以在SDK中定义接口,在此JAR里面提供实现.*/public void initAllJar(){URL[] urls = this.getURLs();for(URL urll:urls){String url = urll.getFile();//重新定义这个架包中的所有类.if(url.endsWith("jar")){File jarFile  = getJarFile(url);JarFile jarFileTemp = null;try {jarFileTemp = new JarFile(jarFile);Enumeration<JarEntry> en = jarFileTemp.entries();while (en.hasMoreElements()) {JarEntry je = en.nextElement();String name = je.getName();if (name.endsWith(CLASS_FILE)) {String className = name.substring(0, name.length()- CLASS_FILE.length());findClass(pathToDot(className));}}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}/*** 转jar包路径和jar文件名为具体文件.** @param root* @param jar* @return*/private File getJarFile(String file) {if (file.startsWith(PREFIX_FILE))file = file.substring(PREFIX_FILE.length());int end = file.indexOf(JAR_URL_SEPERATOR);if (end != (-1))file = file.substring(0, end);return new File(file);}/*** 转路径为包名[/ ==> .]/[\\ ==> .]* @param s* @return*/private String pathToDot(String s) {return s.replace('/', '.').replace('\\', '.');}

其实JDK中已经提供了好几个ClassLoader,大家可以扩展,比如项目中有两个架包版本,结构全部都一样,但是两个架包都必须运行。这时自定义类加载器就有用了。

自定义ClassLoader相关推荐

  1. 自定义ClassLoader实现java应用核心逻辑模块热部署

    http://waterdh.iteye.com/blog/520399 本文主要是根据classloader的特性,结合实际产品环境中遇到的问题,来探讨下JAVA应用中局部模块热部署的可行性. 我们 ...

  2. Java Se:自定义ClassLoader

    JVM是如何知道java.lang包中的类的?JVM又是如何知道我们应用中的类的?我们的应用中明明是有某个类, 但是JVM却抛出ClassNotFoundException,这是为什么?XxxImpl ...

  3. 图解classloader加载class的流程及自定义ClassLoader

    http://longdick.iteye.com/blog/442213 java应用环境中不同的class分别由不同的ClassLoader负责加载. 一个jvm中默认的classloader有B ...

  4. 抽取样本java实验报告_一个自定义classloader的函数抽取壳样本

    原标题:一个自定义classloader的函数抽取壳样本 本文为看雪论坛文章 看雪论坛作者ID:lemn 本文为 看雪安卓高研2w班(7月班)优秀学员作品. 下面先让我们来看看学员的学习心得吧! 学员 ...

  5. 自定义ClassLoader和双亲委派机制

    转载自 自定义ClassLoader和双亲委派机制 ClassLoader ClassLoad:类加载器(class loader)用来加载 Java 类到 Java 虚拟机中.Java 源程序(.j ...

  6. Java高级进阶:自定义ClassLoader

    转载自 Java高级进阶:自定义ClassLoader 假如我们的类不在classpath下,而我们又想读取一个自定义的目录下的class,如果做呢? 读取自定义目录的类 示例读取c:/test/co ...

  7. java源代码加密+使用proguard混淆java web项目代码+自定义Classloader

    如何保护我们的源代码,实际上,应该有几种方法可以使用:1.使用代码混淆器 2.重载应用服务器的classloader 使用代码混淆器proguard进行代码混淆 1.首先下载proGuard.zip到 ...

  8. Java Class的热替换 自定义ClassLoader加载.class

    本文是java热替换的实验,参考了 Java 类的热替换 -- 概念.设计与实现 http://www.ibm.com/developerworks/cn/java/j-lo-hotswapcls/i ...

  9. 为什么要自定义ClassLoader进行类加载

    假如,你开发的java程序都需要从E:\classloader1目录下的类文件中加载class,而不是系统指定的系统目录或者classpath目录下加载,则如何解决? 需要自定义classloader ...

  10. springboot自定义ClassLoader实现同一个jar支持多版本的使用场景【附源码】

    springboot自定义ClassLoader实现同一个jar支持多版本的使用场景 背景 最近业务提出一个业务场景:系统目前支持hive3.1.0版本的数据源适配,但是有个别部门使用的数据源是hiv ...

最新文章

  1. Java并发编程-并发工具包(java.util.concurrent)使用指南(全)
  2. 隧道野蛮模式_基于虚拟隧道的IPsec -华三 MSR26 路由器对接Juniper SSG
  3. linux之ls只显示文件或者文件夹
  4. css html 字竖,CSS实现文字竖排 DIV CSS文字垂直竖列排版显示如何实现?
  5. ie com接口 php_PHP webservie连接.net接口
  6. BUU OJ 做题记录
  7. mysql事务操作代码_Mysql中事务的使用【mysql】
  8. 清除1188.com
  9. 汇川PLC软件下载及安装
  10. 象棋世家 v6.0a 官方
  11. 使用shape绘制阴影图层阴影效果
  12. 移动设备上“精灵图”的制作适配
  13. 如果感觉没有动力或是心情很失落,那就听听战歌吧!(可免费下载)
  14. 4年小Java的心路历程,工作感悟
  15. 0xC000005:Access Violation和指针强制转换问题
  16. Xilinx Ultrascale 多通道高速TDC
  17. CIA反取证工具曝光 安全专家质疑维基解密
  18. 任鸟飞FPS类型游戏绘制和游戏安全,反外挂研究(一)
  19. CH9121串口转以太网模块STM32驱动
  20. (转载)魔兽世界任务制作教学

热门文章

  1. 论文小综 | 文档级关系抽取方法(下)
  2. 论文浅尝 | 神经网络与非神经网络简单知识问答方法的强基线分析
  3. 论文浅尝 | 利用类比推理优化知识图谱向量表示
  4. Android官方开发文档Training系列课程中文版:手势处理之监测通用手势
  5. 谈谈C#反射(Reflection)
  6. iscsi-分区类型
  7. js中实现页面跳转(返回前一页、后一页)
  8. 用户代码未处理EntityCommandExecutionmException报错解决方案
  9. GWT(Google Web Tookit) Eclipse Plugin的zip下载地址(同时提供GWT Designer下载地址)
  10. 操作系统学习笔记-2.1.4进程通信