博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
类加载器的双亲委派及打破双亲委派
阅读量:5897 次
发布时间:2019-06-19

本文共 4218 字,大约阅读时间需要 14 分钟。

一般的场景中使用Java默认的类加载器即可,但有时为了达到某种目的又不得不实现自己的类加载器,例如为了达到类库的互相隔离,例如为了达到热部署重加载功能。这时就需要自己定义类加载器,每个类加载器加载各自的类库资源,以此达到资源隔离效果。在对资源的加载上可以沿用双亲委派机制,也可以打破双亲委派机制。

一、沿用双亲委派机制自定义类加载器很简单,只需继承ClassLoader类并重写findClass方法即可。如下例子:

①先定义一个待加载的类Test,它很简单,只是在构建函数中输出由哪个类加载器加载。

public class Test {    public Test(){        System.out.println(this.getClass().getClassLoader().toString());    }}

②定义一个TestClassLoader类继承ClassLoader,重写findClass方法,此方法要做的事情是读取Test.class字节流并传入父类的defineClass方法即可。然后就可以通过自定义累加载器TestClassLoader对Test.class进行加载,完成加载后会输出“TestLoader”。

public class TestClassLoader extends ClassLoader {
private String name; public TestClassLoader(ClassLoader parent, String name) { super(parent); this.name = name; } @Override public String toString() { return this.name; } @Override public Class
findClass(String name) { InputStream is = null; byte[] data = null; ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { is = new FileInputStream(new File("d:/Test.class")); int c = 0; while (-1 != (c = is.read())) { baos.write(c); } data = baos.toByteArray(); } catch (Exception e) { e.printStackTrace(); } finally { try { is.close(); baos.close(); } catch (IOException e) { e.printStackTrace(); } } return this.defineClass(name, data, 0, data.length); } public static void main(String[] args) { TestClassLoader loader = new TestClassLoader( TestClassLoader.class.getClassLoader(), "TestLoader"); Class clazz; try { clazz = loader.loadClass("test.classloader.Test"); Object object = clazz.newInstance(); } catch (Exception e) { e.printStackTrace(); } }}

二、打破双亲委派机制则不仅要继承ClassLoader类,还要重写loadClass和findClass方法,如下例子:

①定义Test类。

public class Test {    public Test(){        System.out.println(this.getClass().getClassLoader().toString());    }}

②重新定义一个继承ClassLoader的TestClassLoaderN类,这个类与前面的TestClassLoader类很相似,但它除了重写findClass方法外还重写了loadClass方法,默认的loadClass方法是实现了双亲委派机制的逻辑,即会先让父类加载器加载,当无法加载时才由自己加载。这里为了破坏双亲委派机制必须重写loadClass方法,即这里先尝试交由System类加载器加载,加载失败才会由自己加载。它并没有优先交给父类加载器,这就打破了双亲委派机制。

public class TestClassLoaderN extends ClassLoader {
private String name; public TestClassLoaderN(ClassLoader parent, String name) { super(parent); this.name = name; } @Override public String toString() { return this.name; } @Override public Class
loadClass(String name) throws ClassNotFoundException { Class
clazz = null; ClassLoader system = getSystemClassLoader(); try { clazz = system.loadClass(name); } catch (Exception e) { // ignore } if (clazz != null) return clazz; clazz = findClass(name); return clazz; } @Override public Class
findClass(String name) { InputStream is = null; byte[] data = null; ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { is = new FileInputStream(new File("d:/Test.class")); int c = 0; while (-1 != (c = is.read())) { baos.write(c); } data = baos.toByteArray(); } catch (Exception e) { e.printStackTrace(); } finally { try { is.close(); baos.close(); } catch (IOException e) { e.printStackTrace(); } } return this.defineClass(name, data, 0, data.length); } public static void main(String[] args) { TestClassLoaderN loader = new TestClassLoaderN( TestClassLoaderN.class.getClassLoader(), "TestLoaderN"); Class clazz; try { clazz = loader.loadClass("test.classloader.Test"); Object object = clazz.newInstance(); } catch (Exception e) { e.printStackTrace(); } }}

========广告时间========

鄙人的新书《Tomcat内核设计剖析》已经在京东销售了,有需要的朋友可以到 进行预定。感谢各位朋友。

=========================

欢迎关注:

这里写图片描述

你可能感兴趣的文章
nagios短信报警(飞信fetion20080522004-linrh4)
查看>>
【Android游戏开发之六】在SurfaceView中添加组件!!!!并且相互交互数据!!!!...
查看>>
linux 将大文件分成小文件
查看>>
CCNA- 距离矢量路由协议学习
查看>>
企业实践用户邮箱导入/导出(第2部分)
查看>>
我的友情链接
查看>>
如何学习Linux命令-初级篇
查看>>
从Oracle Public Yum为Oracle Linux建立本地的Yum源
查看>>
在 SELECT 查询中使用表表达式
查看>>
静态路由和默认路由
查看>>
谈一谈Spring-Mybatis在多数据源配置上的坑
查看>>
【精益生产】车间现场管理的八大浪费
查看>>
关于阿里开发者招聘节 |这5道笔试真题 你会吗!???
查看>>
C#的异常处理机制
查看>>
vsftp:500 OOPS: could not bind listening IPv4 sock
查看>>
Linux安装BTCPayServer并设置比特币BTC和Lightning支付网关
查看>>
Python 的 with 语句
查看>>
mysql安装,远程连接,以及修改密码
查看>>
Mybatis查询返回Map类型数据
查看>>
java的深拷贝与浅拷贝
查看>>