Skip to content

简单说说你了解的类加载器,可以打破双亲委派么,怎么打破?

cxuan edited this page Oct 30, 2020 · 1 revision

类加载的过程,加载->验证,准备,解析->初始化 类加载器:启动类加载器bootstrapclassload,扩展类加载器(extend class load),应用类加载器( system class load)

1)根类加载器(bootstrap class loader):它用来加载 Java 的核心类,是用原生代码来实现的,并不继承自 java.lang.ClassLoader(负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类)

2)扩展类加载器(extensions class loader):它负责加载JRE的扩展目录,lib/ext或者由java.ext.dirs系统属性指定的目录中的JAR包的类。由Java语言实现,父类加载器为null。

3)系统类加载器(system class loader):被称为系统(也称为应用)类加载器,它负责在JVM启动时加载来自Java命令的-classpath选项、java.class.path系统属性,或者CLASSPATH换将变量所指定的JAR包和类路径。程序可以通过ClassLoader的静态方法getSystemClassLoader()来获取系统类加载器。

双亲委派机制,其工作原理的是,如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器,如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式,即每个儿子都很懒,每次有活就丢给父亲去干,直到父亲说这件事我也干不了时,儿子自己才想办法去完成。

可以打破双亲委派模型, Tomcat 就打破了

Tomcat 类加载原理

1、Tomact 需要隔离,如果用双亲委派模型,在不同的 web 应用下如果有不同业务的 servlet,但是它们同名且全路径相同的Servlet,如果用双亲委派模型不知道加载谁。 所以web应用可以直接用 WebApp ClassLoader 但Tomcat 不行

2、Tomcat 需要共享 (spring) 所以用 Shared Class Loader

然后Tomcat 自己的类又要和 webApp 跟 spring 的类隔离开来 所以要用 Catalina ClassLoader

Catalina ClassLoader 和 Shared ClassLoader 是并级的关系

Tomcat 跟 spring 有公用的 就用父级的 类加载器 Common ClassLoader 来加载

因为需要隔离,所以Tomcat 需要打破这个规则

Clone this wiki locally