双亲委派机制

JDK中ClassLoader默认设计模式

分类

  • BootStrap ClassLoader(启动ClassLoader)
  • Extension ClassLoader (扩展ClassLoader)
  • App ClassLoader (应用ClassLoader/系统ClassLoader)
  • Custom ClassLoader(自定义ClassLoader)

具体加载对象

在这里插入图片描述

  1. 自底向上检查类是否已经加载,加载了就直接获取类
  2. 自顶向下尝试加载
  3. 防止了重复加载和核心类被篡改
    代码实现:
protected Class<?> loadClass(String name, boolean resolve)
	throws ClassNotFoundException{
	synchronized (getClassloadingLock(name)){
		// 查看是否已经被加载了
		Class c = findLoadedClass(name);
		// 没有被加载
		if (c == null){
			long t0 = System.nanoTime();
			try{
				if (parent != null){
					// 请求父类去加载
					c = parent.loadClass(name, false);
				} else {
					c = findBootstrapClassOrNull(name);
				}
			} catch (classNotFoundException e){
				...
			}
	}

所存在的问题

顶层ClassLoader,无法加载底层ClassLoader的类,启动ClassLoader无法加载生成App ClassLoader的实例对象。这就导致Bootstrap ClassLoader无法看到下层中的内容。

解决方法

Thread.setContextClassLoader()

  • 上下文加载器
  • 是一个角色【根据应用场景来设置】
  • 用以解决顶层ClassLoader无法访问底层ClassLoader的类问题
  • 基本思想是:在顶层ClassLoader中,传入底层ClassLoader的实例

双亲模式的破坏

  • Tomcat的WebappClassLoader会先加载自己的Class,找不到再委托parent:保证公用的一起加载,私有的自己加载
protected synchronized Class<?> boadClass(String name, boolean resovle) throws ClassNotFoundException{
	// 检查该类是否已经被加载&尝试自己加载
	Class re = findClass(name);
	if (re == null){ // 没有加载成功
		System.out.Println("无法载入类:" + name + "需要请求父类加载");
		// 交给父类进行加载
		return super.loadClass(name, resolve);
	}
	return re;
}	

protected Class<?> findClass(String className) throws 				ClassNotFoundException {
	// 判断是否加载--防止重复加载
	Class clazz = this.findLoadedClass(className);
	if (null == clazz) {
		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);
			// 省略部分代码
			fis.close();
			byte[] bytes = baos.toByteArray();
			// 自己去加载该类
			clazz = defineClass(className, bytes, 0, bytes.length);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	return clazz;
}
  • OSGI的ClassLoader形成网状结构,根据需要自由加载Class:热加载
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值