Java tomcat中的类加载器和安全机制你了解吗

目录
  • 类加载器
  • 双亲委派
  • URLClassLoader
  • Tomcat中类加载器架构
  • 安全机制
  • 总结

类加载器

java中的类并不是一次加载完成的,而是按需加载。类加载器是用于加载java类到java虚拟机中的组件,它负责读取java字节码,并转换成 java.lang.Class 的一个实例,使字节码.class文件可以运行。一般类加载器负责根据一个指定的类找到对应的字节码,然后根据这些字节码定义一个java类。另外,它还可以加载资源,包括图像文件和配置文件。

类加载器可以使java类动态地加载到jvm中并运行,即可在程序运行时再加载类,提供了很灵活的动态加载方式。

  • 启动类加载器(Bootstrap ClassLoader):加载对象是java核心库,把一些核心的java类加载进jvm中,这个加载器采用原生代码(c/c++)实现,并不继承java.lang.classLoader,它是所有其他类加载器的最终父类加载器,负责加载<java_home>/jre/lib目录下jvm指定的类库。它属于jvm整体的一部分,jvm一旦启动就将这些指定的类加载到内存中国,避免以后过多的I/O操作,提高系统的运行效率。启动类加载器无法被程序直接使用。
  • 扩展类加载器(Extension ClassLoader):加载对象是java的扩展库,即加载<java_home>/jar/lib/ext目录里的类。这个类是由启动类加载器加载,但因为启动类加载器并非用java实现,已经脱离了java体系,所以如果尝试调用扩展类加载器的getParent()方法获取父类的加载器会得到null。然而,它的父类加载器是启动类加载器。
  • 应用类加载器(application ClassLoader):也叫系统类加载器(system classloader),它负责加载用户类路径自定的类库,如果程序没有自己定义类加载器,就默认使用应用类加载器。它是由启动类加载器加载,但他的父加载类被设置成了扩展类加载器。如果使用这个加载器,通过classloader.getSystemClassLoader()获取。

双亲委派

双亲委派时,会将先委托给父类加载器加载,除非父类加载器没有,才自己加载。

这种模型要求,除了顶层的启动类加载器外,其他的类加载器都要有⾃⼰的⽗类加载器。 假如有⼀个类要加载进来,⼀个类加载器并不会⻢上尝试⾃⼰将其加载,⽽是委派给⽗类加载器,⽗类加载器收到后⼜尝 试委派给其⽗类加载器,以此类推,直到委派给启动类加载器,这样⼀层⼀层往上委派。 只有当⽗类加载器反馈⾃⼰没法完成这个加载时,⼦加载器才会尝试⾃⼰加载。 通过这个机制,保证了 Java 应⽤所使⽤的都是同⼀个版本的 Java 核⼼库的类,同时这个机制也保证了安全性。 设想如果应⽤程序类加载器想要加载⼀个有破坏性的 java.lang.System 类,双亲委派模型会⼀层层向上委派,最终委派给启动类加载器,⽽启动类加载器检查到缓存中已经有了这个类,并不会再加载这个有破坏性的 System 类。

另外,类加载器还拥有全盘负责机制,即当⼀个类加载器加载⼀个类时,这个类所依赖的、 引⽤的其他所有类都由这个类加载器加载,除⾮在程序中显式地指定另外⼀个类加载器加载。

在 Java 中,我们⽤完全匹配类名来标识⼀个类,即⽤包名和类名。 ⽽在 JVM 中,⼀个类由完全匹配类名和⼀个类加载器的实例 ID 作为唯⼀标识。 也就是说,同⼀个虚拟机可以有两个包名、 类名都相同的类,只要它们由两个不同的类加载器加载。 当我们在 Java 中说两个类是否相等时,必须在针对同⼀个类加载器加载的前提下才有意义,否则,就算是同样的字节码,由不同的类加载器加载,这两个类也不是相等的。 这种特征为我们提供了隔离机制,在 Tomcat 服务器中它是⼗分有⽤的。

URLClassLoader

我们在使⽤⾃定义类加载去加载类时,我们需要指明该去哪些资源中进⾏加载,所以JDK提供了URLClassLoader来⽅便我们使⽤,我们在创建URLClassLoader时需要传⼊⼀些URLs,然后在使⽤这个URLClassLoader加载类时就会从这些资源中去加载。

Tomcat中⾃定义的类加载器

Tomcat 拥有不同的⾃定义类加载器,以实现对各种资源库的控制。 ⼀般来说,Tomcat 主要⽤类加载器解决以下 4 个问题。

  • 同⼀个Tomcat中,各个Web应⽤之间各⾃使⽤的Java类库要互相隔离。
  • 同⼀个Tomcat中,各个Web应⽤之间可以提供共享的Java类库。

为了使Tomcat不受Web应⽤的影响,应该使服务器的类库与应⽤程序的类库互相独⽴。

-Tomcat⽀持热部署。

在 Tomcat中,最重要的⼀个类加载器是 Common 类加载器,它的⽗类加载器是应⽤程序类加载器,负责加载 $ CATALINA_ BASE/lib、$CATALINA_HOME/lib 两个⽬录下所有的.class ⽂件与.jar ⽂件。

-Tomcat中⼀般会有多个WebApp类加载器-WebAppClassLoader ,每个类加载器负责加载⼀个 Web 程序。 它的⽗类加载器是Common类加载器。

由于每个 Web 应⽤都有⾃⼰的 WebApp 类加载器,很好地使多个 Web 应⽤程序之间互相隔离且能通过创建新的 WebApp类加载器达到热部署。 这种类加载器结构能有效使 Tomcat 不受 Web 应⽤程序影响,

⽽ Common 类加载器的存在使多个 Web 应⽤程序能够互相共享类库

Tomcat中类加载器架构

源码位置如下,在bootstrap类的初始化过程中,初始了三个类加载:commonLoader,catalinaLoader,sharedLoader

    private void initClassLoaders() {
        try {
            commonLoader = createClassLoader("common", null);
            if (commonLoader == null) {
                // no config file, default to this loader - we might be in a 'single' env.
                commonLoader = this.getClass().getClassLoader();
            }
            catalinaLoader = createClassLoader("server", commonLoader);
            sharedLoader = createClassLoader("shared", commonLoader);
        } catch (Throwable t) {
            handleThrowable(t);
            log.error("Class loader creation threw exception", t);
            System.exit(1);
        }
    }

安全机制

Tomcat中设置了了⼀些安全策略,默认的策略⽂件为conf/catalina.policy

Tomcat中设置了安全策略,规定了Tomcat在运⾏过程中拥有的权限,Tomcat管理者可以修改该权限, 但是Tomcat中有⼀些类是必须能够被访问到的,所有Tomcat中在启动过程中会提前去加载这些类,如果 发现没有对应的权限,那么将会启动失败。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • 详解tomcat热部署和热加载的方法

    详解tomcat热部署和热加载的方法 我在项目开发过程中,经常要改动Java/JSP 文件,但是又不想从新启动服务器(服务器从新启动花时间),想直接获得(debug)结果.有两种方式热部署 和热加载: 1.热加载:在server.xml -> context 属性中 设置 reloadable="true" <Context docBase="xxx" path="/xxx" reloadable="true"/&

  • Tomcat 类加载器的实现方法及实例代码

    Tomcat 内部定义了多个 ClassLoader,以便应用和容器访问不同存储库中的类和资源,同时达到应用间类隔离的目的. 1. Java 类加载机制 类加载就是把编译生成的 class 文件,加载到 JVM 内存中(永久代/元空间). 类加载器之所以能实现类隔离,是因为两个类相等的前提是它们由同一个类加载器加载,否则必定不相等. JVM 在加载时,采用的是一种双亲委托机制,当类加载器要加载一个类时,加载顺序是: 首先将请求委托给父加载器,如果父加载器找不到要加载的类然后再查找自己的存储库尝试

  • tomcat加载jar异常问题的分析与解决

    现象描述: 项目使用springboot启动一个web项目,在启动阶段看到console中出现了异常"1.10.3-1.4.3\hdf5.jar  系统找不到指定的文件",虽然这些异常不影响项目的正常运行,但作为一个严谨的技术人员,看到这些异常就像见到仇人一样,一定要除之而后快. java.io.FileNotFoundException: D:\.m2\repository\org\bytedeco\javacpp-presets\hdf5-platform\1.10.3-1.4.3

  • 解决eclipse启动tomcat时不能加载web项目的问题

    问题描述: eclipse启动tomcat时,不能加载web项目,但是把war包丢进tomcat的webapps下是能正常运行的 解决方式: 右键项目--打开Properties--找到Deployment Assembly--将WebContent修改成你的项目webapp路径 eclipse与tomcat绑定成功后却无法访问自己的web项目下的HTML文件 WARNING: [SetContextPropertiesRule]{Context} Setting property 'sourc

  • Tomcat无法加载css和js等静态资源文件的解决思路

    解决思路有两个 一是,你使用了Apache服务器,html不交给Tomcat处理,所以你找不到Html等静态资源,所以你先停掉阿帕奇,然后只用Tomcat猫试试. 二是,像我一样,使用了Jetty开发程序,但是打war包的时候忘记干掉web.xml中的jetty修改静态资源的代码.如下,干掉即可. 复制代码 代码如下: <servlet> <servlet-name>default</servlet-name> <!-- <servlet-class>

  • Java tomcat中的类加载器和安全机制你了解吗

    目录 类加载器 双亲委派 URLClassLoader Tomcat中类加载器架构 安全机制 总结 类加载器 java中的类并不是一次加载完成的,而是按需加载.类加载器是用于加载java类到java虚拟机中的组件,它负责读取java字节码,并转换成 java.lang.Class 的一个实例,使字节码.class文件可以运行.一般类加载器负责根据一个指定的类找到对应的字节码,然后根据这些字节码定义一个java类.另外,它还可以加载资源,包括图像文件和配置文件. 类加载器可以使java类动态地加载

  • Java中的类加载器_动力节点Java学院整理

    从java的动态性到类加载机制 Java是一种动态语言.那么怎样理解这个"动态"呢?或者说一门语言具备了什么特性,才能称之为动态语言呢?对于java,我是这样理解的. JVM(java虚拟机)执行的不是本地机器码指令,而是执行一种称之为字节码的指令(存在于class文件中).这就要求虚拟机在真正执行字节码之前,先把相关的class文件加载到内存中.虚拟机不是一次性加载所有需要的class文件,因为它在执行的时候根本不会知道以后会用到哪些class文件.它是每用到一个类,就会在运行时&q

  • Java实现的自定义类加载器示例

    本文实例讲述了Java实现的自定义类加载器.分享给大家供大家参考,具体如下: 一 点睛 1 ClassLoader类有如下两个关键方法: loadClass(String name, boolean resolve):该方法为ClassLoader的入口点,根据指定的二进制名称来加载类,系统就是调用ClassLoader的该方法来获取指定类对应的Class对象. findClass(String name):根据二进制名称来查找类. 如果需要实现自定义的ClassLoader,可以通过重写以上两

  • JVM中ClassLoader类加载器的深入理解

    JVM的体系结构图 先来看一下JVM的体系结构,如下图: JVM的位置 JVM的位置,如下图: JVM是运行在操作系统之上的,与硬件没有直接的交互,但是可以调用底层的硬件,用JIN(Java本地接口调用底层硬件) JVM结构图中的class files文件 class files文件,是保存在我们电脑本地的字节码文件,.java文件经过编译之后,就会生成一个.class文件,这个文件就是class files所对应的字节码文件,如下图: JVM结构图中的类加载器ClassLoader的解释 类加

  • Java基础之自定义类加载器

    一.类加载器关系 自定义类加载器 创建一个类继承ClassLoader类,同时重写findClass方法,用于判断当前类的class文件是否已被加载 二.基于本地class文件的自定义类加载器 本地class文件路径 自定义类加载器: //创建自定义加载器类继承ClassLoader类 public class MyClassLoader extends ClassLoader{ // 包路径 private String Path; // 构造方法,用于初始化Path属性 public MyC

  • Java Swing中JTable渲染器与编辑器用法示例

    本文实例讲述了Java Swing中JTable渲染器与编辑器用法.分享给大家供大家参考,具体如下: JTable的内容.外观.事件响应在很大程度上是由渲染器与编辑器控制的.具体说来,渲染器负责单元格的外观比如前景色.背景色,以及单元格提示:编辑器负责单元格的内容和事件响应.编辑器默认为文本框形式,也可以使用下拉菜单.按钮.单选按钮等形式.下面通过一个demo程序来说明渲染器与编辑器的基本用法. JButtonTableExample.java package awtDemo; import j

  • Java Spring中Quartz调度器详解及实例

    一.Quartz的特点 * 按作业类的继承方式来分,主要有以下两种: 1.作业类继承org.springframework.scheduling.quartz.QuartzJobBean类的方式 2.作业类不继承org.springframework.scheduling.quartz.QuartzJobBean类的方式 注:个人比较推崇第二种,因为这种方式下的作业类仍然是POJO. * 按任务调度的触发时机来分,主要有以下两种: 1.每隔指定时间则触发一次,对应的调度器为org.springf

  • Java语言中的自定义类加载器实例解析

    本文研究的主要是Java语言中的自定义类加载器实例解析的相关内容,具体如下. 自己写的类加载器 需要注意的是:如果想要对这个实例进行测试的话,首先需要在c盘建立一个c://myjava的目录.然后将相应的java文件放在这个目录中.并将产生的.clas文件放在c://myjava/com/lg.test目录下,否则是找不到的.这是要注意的.. class FileClassLoader : package com.lg.test; import java.io.ByteArrayOutputSt

  • Java类加载器层次结构原理解析

    类加载器的层次结构: 引导类加载器(bootstrap class loader) 用来加载java的核心库(JAVA_HOME/jre/lib/rt.jar,或sun.boot.class.path路径下的内容),是用原生代码来实现的(C实现的),并不继承自java.lang.ClassLoader. 加载扩展类和应用程序类加载器,并指定它们的父类加载器. 扩展类加载器(extensions class loader) 用来加载java的扩展库(JAVA_HOME/jre/lib/ext/*.

  • 详解Java类加载器与双亲委派机制

    目录 引子 了解.class文件 类加载的过程 类加载器 与 双亲委派机制 ClassLoader 自定义类加载器 编写一个自定义的类加载器 为什么我们这边要打破双亲委派机制 自定义类加载器时,如何打破双亲委派机制 SPI机制 与 线程上下文类加载器 JDBC Tomcat SpringBoot Starter 尾语 引子 大家想必都有过平时开发springboot 项目的时候稍微改动一点代码,就得重启,就很烦 网上一般介绍 2种方式 spring-boot-devtools,或者通过JRebe

随机推荐