tomcat 著名的双亲委托机制
- 就是有类需要加载时就委托父类去加载 一直到顶级的 Bootstrap 都没有自己才加载 ,自己也没有就报错
类加载器
- Bootstrap ClassLoader:JVM内置的类加载器,用来加载Java核心类库,例如rt.jar、resources.jar等等。
- Extension ClassLoader:用来加载Java扩展类库,例如jre/lib/ext目录下的jar包。
- Common ClassLoader:主要用于加载Tomcat共享的类库,例如Tomcat中的servlet-api.jar和jsp-api.jar等,这些类库被所有的Web应用程序共享,因此需要通过一个公共的类加载器来加载
- System ClassLoader:也称为应用程序类加载器(Application ClassLoader),用来加载系统类和应用程序类,例如用户自定义的类和第三方库中的类。
- WEB Application ClassLoader:Web应用程序创建一个独立的类加载器,这样可以保证每个Web应用程序之间的类和资源相互隔离,互不干扰。
什么情况需要打破双亲委托机制
- 每个web Application 依赖的上级类名称一致但是版本不一样
如何打破双亲委托机制
- 继承URLClassLoader或者ClassLoader类,然后重写loadClass()方法
- 自己加载时就从自己路劲加载 没有时候就从父类加载 super.loadClass()
实例代码
public class CustomClassLoader extends ClassLoader {
private String classPath;
public CustomClassLoader(String classPath) {
this.classPath = classPath;
}
@Override
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
// 首先尝试从自定义的类路径中加载类
Class<?> c = findClass(name);
if (c != null) {
if (resolve) {
resolveClass(c);
}
return c;
}
// 如果自定义的类路径中不存在该类,则调用父类加载器进行加载
return super.loadClass(name, resolve);
}
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
// 从指定路径或者jar包中加载类
byte[] classBytes = loadClassBytes(name);
if (classBytes == null) {
throw new ClassNotFoundException(name);
}
// 定义类
Class<?> c = defineClass(name, classBytes, 0, classBytes.length);
if (c == null) {
throw new ClassNotFoundException(name);
}
return c;
}
private byte[] loadClassBytes(String name) {
// 实现从指定路径或者jar包中加载类文件的逻辑
// 省略具体实现细节
}
}
标签:类库,name,委托,ClassLoader,jar,String,双亲,tomcat,加载
From: https://www.cnblogs.com/guanchaoguo/p/17315460.html