Tomcat打破双亲委派模型

news2024/11/28 8:29:23

tomcat的类加载器结构

tomcat的类加载(loadClass)过程

和原本的双亲委派模型思路差不多,先看有没有加载过。

  1. 先在本地 Cache 查找该类是否已经加载过,也就是说 Tomcat 的类加载器是否已经加载过这个类。

  1. 如果 Tomcat 类加载器没有加载过这个类,再看看系统类加载器是否加载过。

  1. 如果都没有,就让ExtClassLoader去加载,这一步比较关键,目的防止 Web 应用自己的类覆盖 JRE 的核心类。因为 Tomcat 需要打破双亲委托机制,假如 Web 应用里自定义了一个叫 Object 的类,如果先加载这个 Object 类,就会覆盖 JRE 里面的那个 Object 类,这就是为什么 Tomcat 的类加载器会优先尝试用 ExtClassLoader 去加载,因为 ExtClassLoader 会委托给 BootstrapClassLoader 去加载,BootstrapClassLoader 发现自己已经加载了 Object 类,直接返回给 Tomcat 的类加载器,这样 Tomcat 的类加载器就不会去加载 Web 应用下的 Object 类了,也就避免了覆盖 JRE 核心类的问题。

  1. 如果 ExtClassLoader 加载器加载失败,也就是说 JRE 核心类中没有这类,那么就在本地 Web 应用目录下查找并加载。

  1. 如果本地目录下没有这个类,说明不是 Web 应用自己定义的类,那么由系统类加载器去加载。这里请你注意,Web 应用是通过Class.forName调用交给系统类加载器的,因为Class.forName的默认加载器就是系统类加载器。

  1. 如果上述加载过程全部失败,抛出 ClassNotFound 异常。

public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
 
    synchronized (getClassLoadingLock(name)) {
 
        Class<?> clazz = null;
 
        //1. 先在本地 cache 查找该类是否已经加载过
        clazz = findLoadedClass0(name);
        if (clazz != null) {
            if (resolve)
                resolveClass(clazz);
            return clazz;
        }
 
        //2. 从系统类加载器的 cache 中查找是否加载过
        clazz = findLoadedClass(name);
        if (clazz != null) {
            if (resolve)
                resolveClass(clazz);
            return clazz;
        }
 
        // 3. 尝试用 ExtClassLoader 类加载器类加载,为什么?
        ClassLoader javaseLoader = getJavaseClassLoader();
        try {
            clazz = javaseLoader.loadClass(name);
            if (clazz != null) {
                if (resolve)
                    resolveClass(clazz);
                return clazz;
            }
        } catch (ClassNotFoundException e) {
            // Ignore
        }
 
        // 4. 尝试在本地目录搜索 class 并加载
        try {
            clazz = findClass(name);
            if (clazz != null) {
                if (resolve)
                    resolveClass(clazz);
                return clazz;
            }
        } catch (ClassNotFoundException e) {
            // Ignore
        }
 
        // 5. 尝试用系统类加载器 (也就是 AppClassLoader) 来加载
            try {
                clazz = Class.forName(name, false, parent);
                if (clazz != null) {
                    if (resolve)
                        resolveClass(clazz);
                    return clazz;
                }
            } catch (ClassNotFoundException e) {
                // Ignore
            }
       }
    
    //6. 上述过程都加载失败,抛出异常
    throw new ClassNotFoundException(name);
}

tomcat的类加载(findClass)过程

public Class<?> findClass(String name) throws ClassNotFoundException {
    ...
    
    Class<?> clazz = null;
    try {
            //1. 先在 Web 应用目录下查找类 
            clazz = findClassInternal(name);
    }  catch (RuntimeException e) {
           throw e;
       }
    
    if (clazz == null) {
    try {
            //2. 如果在本地目录没有找到,交给父加载器去查找
            clazz = super.findClass(name);
    }  catch (RuntimeException e) {
           throw e;
       }
    
    //3. 如果父类也没找到,抛出 ClassNotFoundException
    if (clazz == null) {
        throw new ClassNotFoundException(name);
     }
 
    return clazz;
}

findClass方法大致步骤:

  1. 先在 Web 应用本地目录下查找要加载的类。

  1. 如果没有找到,交给父加载器去查找,它的父加载器就是上面提到的系统类加载器 AppClassLoader。

  1. 如何父加载器也没找到这个类,抛出 ClassNotFound 异常。

Tomcat是如何打破双亲委派机制的呢?

Tomcat是先去本地目录加载,为了避免本地目录覆盖掉JRE的核心类,如java.lang包等,先尝试用ExtClassLoader加载,这样即能打破双亲委派机制,有避免了覆盖掉核心类。

为什么不是尝试用AppClassLoader加载呢?

如果是尝试用AppClassLoader,这样不又变会双亲委派机制了嘛。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/166597.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【学习笔记】【Pytorch】张量(Tensor)的基础操作

【学习笔记】【Pytorch】张量&#xff08;Tensor&#xff09;的基础操作一、创建张量1.使用数据创建张量2.无需数据的创建选项3.torch.Tensor与torch.tensor的区别4.PyTorch中张量的创建方法的选择二、张量的属性1.张量的 torch.dtype2.张量的 torch.device3.张量的 torch.layo…

阿维塔冲击年10万台订单,第二款车型Q2发布

1月13日&#xff0c;阿维塔科技在重庆总部召开渠道合作伙伴大会。今年&#xff0c;阿维塔计划推出&#xff1a; •阿维塔11后驱版本 •并发布第二款产品&#xff0c;代号E12&#xff0c;定位中大型轿车。阿维塔今年计划冲击10万辆订单目标。在当前CHN平台的基础上&#xff0c;阿…

Openresty记录笔记

最近由于项目需要学习了安全代理的相关知识&#xff0c;其实刚开始的时候是非常需要一个入门的介绍&#xff0c;大概说明下这个到底是个什么东西&#xff0c;能干啥&#xff0c;简单的原理是什么&#xff0c;为此我记录下我看完用完的心得&#xff0c;记录成笔记。 一般我们代码…

Redis 持久化详解

目录一、简介二、RDB持久化2.1、SAVE2.2、BGSAVE2.3、SAVE选项2.4、RDB文件结构2.5、RDB文件载入三、AOF持久化3.1、开启AOF功能3.2、配置AOF文件的冲洗频率3.3、AOF重写3.3.1、BGREWRITEAOF命令&#xff08;手动&#xff09;3.3.2、AOF重写配置选项&#xff08;自动&#xff0…

Android | Service

Android Service Service 概念 实现程序后台运行的解决方案&#xff0c;一种可在后台执行长时间运行操作而不提供界面的应用组件。Service 的运行不依赖于任何用户界面&#xff0c;即使程序被切换到后台&#xff0c;或者用户打开了另外一个应用程序&#xff0c;Service 仍然能…

Vue3——第十五章(计算属性:computed)

一、基础示例 模板中的表达式虽然方便&#xff0c;但也只能用来做简单的操作。如果在模板中写太多逻辑&#xff0c;会让模板变得臃肿&#xff0c;难以维护。推荐使用计算属性来描述依赖响应式状态的复杂逻辑。 在这里定义了一个计算属性 publishedBooksMessage。computed() 方…

【设计模式】创建型模式·原型模式

设计模式学习之旅(五) 查看更多可关注后查看主页设计模式DayToDay专栏 一. 概述 用一个已经创建的实例作为原型&#xff0c;通过复制(克隆)该原型对象来创建一个和原型对象相同的新对象。 原型模式包含如下角色&#xff1a; 抽象原型类&#xff1a;规定了具体原型对象必须实现…

Java基础(二)

1.标识符标识符&#xff1a;由数字、字符、下划线、$组成&#xff08;不能以数字、下划线开头&#xff09;java严格区分大小写2.命名规范包名&#xff1a;多单词组成时所有字母全部小写类名、接口名&#xff1a;多单词组成时&#xff0c;所有单词首字母大写变量名、方法名&…

屏幕录制工具哪个好用?分享3款相见恨晚的软件

在我们的日常生活中&#xff0c;我们经常使用截图和手机屏幕记录功能来记录一些重要的内容。然而&#xff0c;录制的图片清晰度很低&#xff0c;或者需要不断的截图&#xff0c;这很容易出错一些重要的内容&#xff0c;这个时候就需要进行录屏了。那么电脑上的屏幕录制工具哪个…

group by详解

group by功能 在SQL中group by主要用来进行分组统计&#xff0c;分组字段放在group by的后面&#xff1b;分组结果一般需要借助聚合函数实现。 group by语法结构 1、常用语法 语法结构 SELECT column_name1,column_name2, … 聚合函数1,聚合函数2 , … FROM table_name GROUP…

电脑删除了大文件怎么恢复?看看这四种方法

电脑能够帮助我们存储大量的文件&#xff0c;比如视频、文档、音频等&#xff0c;但是随着时间的流逝&#xff0c;有些文件所存在的意义也变得毫无价值了&#xff0c;这时候很多小伙伴都会选择删除操作&#xff0c;可是由于电脑磁盘内容过多&#xff0c;容易面临重要文件被误删…

硬件仿真加速器与原型验证平台

基于软件仿真工具对于动辄几百万门的ASIC验证而言&#xff0c;几乎显得力不从心。不管是从成本还是从性能的角度来看&#xff0c;使用硬件仿真器或者基于FPGA的原型验证平台&#xff0c;几乎是验证工程师的不二法门。因为基于硬件的环境能够极大的提高验证的速度&#xff0c;增…

Promise(基础)

Promise是什么 1.promise是一门新的技术&#xff08;ES6规范&#xff09; 2.Promise是JS中一编程的解决方案&#xff08;旧的解决方案是单纯的使用回调函数&#xff09; 3.promise一个构造函数&#xff0c;promise队形用来封装一个一步操作并可以获取其成功/失败的结果值。 注…

sparksql案例实操

sparksql案例实操解决语句如下 select * from( select , rank()over(partition by area order by clickCnt desc) from(select area, product_name, count()as clickCnt from( select a.*, p.product_name, c.area, c.city_name from user_visit_action a join product_info p…

Dubbo与Spring集成

Dubbo框架常被当作第三方框架集成到应用中&#xff0c;当Spring集成Dubbo框架后&#xff0c;为什么在编写代码的时候&#xff0c;只用了DubboReference注解就可以调用提供方的服务了呢&#xff1f;这篇笔记就是分析Dubbo框架是怎么与Spring结合的。 现状integration层代码编写…

关于嵌入式学习和规划,求指点?

在知乎上收到的一个提问问题&#xff1a;各位大佬好&#xff0c;我先说说基本情况&#xff0c;28岁&#xff0c;北京&#xff0c;嵌入式软开&#xff0c;军工行业。硕士毕业一年半。工作不忙收获很少&#xff0c;造成我自己特别迷茫&#xff0c;没有了方向&#xff0c;自己学没…

【C++】Hash闭散列

目录 一、哈希的概念 1.1 哈希冲突 1.2 哈希函数 1.3 装载因子 二、闭散列 2.1 线性探测 2.2 Insert 插入 2.3 Find 查找 2.4 Erase删除 2.5 插入复杂类型 2.6 二次探测 三、源代码与测试用例 3.1 hash源代码 3.2 测试用例 一、哈希的概念 在前面学习了二叉搜索…

多巴胺聚乙二醇多巴胺,Dopamine-PEG-Dopamine简介,多巴胺是具有正性肌力活动的单胺化合物

产品名称&#xff1a;多巴胺聚乙二醇多巴胺&#xff0c;双多巴胺聚乙二醇&#xff08;Dopamine-PEG-Dopamine&#xff09; 中文别名&#xff1a;多巴胺PEG多巴胺&#xff0c;双多巴胺聚乙二醇 英文名称&#xff1a;Dopamine-PEG-Dopamine 存储条件&#xff1a;-20C&#xff0…

磨金石教育影视技能干货分享|浅析中国CG特效的发展现状

中国CG特效的发展2015年是一个分水岭。在2015年之前&#xff0c;中国CG 特效发展是混乱的&#xff0c;不成熟的。总体表现就是技术水平不足&#xff0c;缺少人才培养的体系。当时从事CG的公司&#xff0c;大概有两个类型&#xff1a;“技术型与业务型”。所谓技术型的公司&…

设计模式_结构型模式 -《装饰器模式》

设计模式_结构型模式 -《装饰器模式》 笔记整理自 黑马程序员Java设计模式详解&#xff0c; 23种Java设计模式&#xff08;图解框架源码分析实战&#xff09; 概述 我们先来看一个快餐店的例子。 快餐店有炒面、炒饭这些快餐&#xff0c;可以额外附加鸡蛋、火腿、培根这些配菜…