双亲委派机制浅谈

可以看看下面这些文章,讲的很好
https://blog.csdn.net/codeyanbao/article/details/82875064

https://www.jianshu.com/p/1e4011617650
双亲委派机制
在这里插入图片描述

为什么要有双亲委派机制?(优点)?

防止重复加载.class
保证核心.class不会被篡改

自定义一个String,会使用哪一个包

打破了双亲委派的例子

Tomcat中的web 容器类加载器也是破坏了双亲委托模式的,自定义的WebApplicationClassLoader除了核心类库外,都是优先加载自己路径下的Class;

如果我们不想用双亲委派模型怎么办?(打破双亲委派)

为了避免双亲委托机制,我们可以自己定义一个类加载器,然后重写 loadClass() 即可。

原文
https://www.zhihu.com/question/45022217
步骤如下
(1)继承ClassLoader
(2)重写findClass()方法
(3)调用defineClass()方法下面写一个自定义类加载器:指定类加载路径在D盘下的lib文件夹下
新建立一个Test类

 package com.test; 
 
 public class Test { 
    public void say(){
        System.out.println("Hello MyClassLoader"); 
    } 
}

cmd控制台执行javac Test.java,将生成的Test.class文件放到D盘lib文件夹->com文件夹->test文件夹下;
自定义类加载器,代码如下:

package test;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class MyClassLoader extends ClassLoader
{
	private String classpath;

	public MyClassLoader(String classpath)
	{
		this.classpath = classpath;
	}

	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException
	{
		try
		{
			byte[] classDate = getClassBinaryData(name);
			if (classDate == null)
			{
			}
			else
			{ // defineClass方法将字节码转化为类
				return defineClass(name, classDate, 0, classDate.length);
			}
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		return super.findClass(name);
	} // 返回类的字节码

	private byte[] getClassBinaryData(String className) throws IOException
	{
		InputStream in = null;
		ByteArrayOutputStream out = null;
		String path = classpath + File.separatorChar + className.replace('.', File.separatorChar) + ".class";
		try
		{
			in = new FileInputStream(path);
			out = new ByteArrayOutputStream();
			byte[] buffer = new byte[2048];
			int len = 0;
			while ((len = in.read(buffer)) != -1)
			{
				out.write(buffer, 0, len);
			}
			return out.toByteArray();
		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		}
		finally
		{
			in.close();
			out.close();
		}
		return null;
	}
}

测试代码:

package test;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class TestMyClassLoader
{
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
			NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException
	{ // 自定义类加载器的加载路径
		MyClassLoader myClassLoader = new MyClassLoader("D:\\lib"); // 包名+类名
		Class c = myClassLoader.loadClass("com.test.Test");
		if (c != null)
		{
			Object obj = c.newInstance();
			Method method = c.getMethod("say", null);
			method.invoke(obj, null);
			System.out.println(c.getClassLoader().toString());
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值