,才会真正建立 Catalina ClassLoader 和 Shared ClassLoader 的实例,否则在用到这两个类加载器的地方都会用 Common ClassLoader 的实例代替,而默认的配置文件中是没有设置这两个...loader 项的 (4)WebApp ClassLoader:Tomcat 可以存在多个 WebApp ClassLoader 实例,每个应⽤程序都会有⼀个独⼀⽆⼆的 WebApp ClassLoader...有没有加载过这个类 (2)如果 Tomcat 没有加载过这个类,则从系统类加载器的 cache 缓存中查找是否加载过 (3)如果没有,则使用 ExtClassLoader 类加载器类加载,重点来了,Tomcat...当然还有其他原因,如: (1)保证 Web 容器自身的安全不受部署的 Web 应用程序影响,所以 Tomcat 使用的类库要与部署的应用的类库相互独立 (2)保证部分基础类不会被同时加载,有些类库 Tomcat...与部署的应用可以共享,比如说 servlet-api (3)保证部署在同一个 Web 容器的应用之间的类库可以共享,这听起来好像主要原因相互矛盾,但其实这很合理,类被类加载器加载到虚拟机后,会存放在方法区的永久代中
初始化过程: 如果类还没有被加载和连接,那就先进行加载和连接 如果类存在父类,并且父类没有初始化,那就先初始化直接父类 如果类中存在初始语句,顺序执行初始化语句 类的初始化阶段是执行类构造器方法clinit...通常,我们会描述两个类比较是否相等,这个比较的前提是只有这两个类再同一个类加载器加载才有意义,否则就算这两个类是来源同一个class文件,被同一个JVM加载,只要类加载器不同,那就必定不相等(这里的相等包括...加载\lib\ext目录,或被java.ext.dirs系统变量所指定的路径中的类库。 允许用户将类库放置在ext目录以扩展JavaSE功能。...1、修改类的加载方法,如tomcat中多个war工程可以独立运行;保证了各个war中的jar不会冲突。 2、防止源码泄露,对class字节码进行编码加密,再在laod过程中对其解密。 .........在这之前,如果类路径中确实了运行时依赖的类型,那就只能等程序运行到发生该类型的加载,连接时才会报运行异常。
,也就是说jvm自带的类加载器所加载的类,在虚拟机还没有退出时,始终不会被卸载,当然也有特例 如:我们自己定义的类加载器的类是可以被卸载的....两个类来源于同一个 Class 文件,被同一个虚拟机加载,但是加载它们的类加载器不同,那这两个类也不相等 那有的小伙伴就有疑惑了,还有很多类加载器吗? emm..那加载的顺序呢?会不会重复加载了?...CLASSPATH环境变量所指定的jar包和类路径。...tomcat之所以造了一堆自己的classloader,大致是出于下面三个原因: 对于各个 webapp中的 class和 lib,需要相互隔离,不能出现一个应用中加载的类库会影响另一个应用的情况,而对于许多应用...相信大家一定为 tomcat修改文件不用重启就自动重新装载类库而惊叹吧。 破坏双亲委派的方式 双亲委派机制原则在loadclass方法中。只需要绕开loadclass方法中即可。
这句话可以表达得更通俗一些:比较两个类是否“相等”,只有在这两个类是由同一个类加载器加载的前提下才有意义。...否则,即使这两个类来源于同一个Class文件,被同一个虚拟机加载,只要加载它们的类加载器不同,那这两个类就必定不相等。...1)启动类加载器(Bootstrap ClassLoader):前面已经介绍过,这个类加载器负责将存放在<JAVA_HOME>\lib目录中的,或者被-Xbootclasspath参数所指定的路径中的,...这是最基本的需求,两个不同的应用程序可能会依赖同一个第三方类库的不同版本,不能要求一个类库在一个服务器中只有一份,服务器应当保证两个应用程序的类库可以互相独立使用。...和Shared ClassLoader的实例,否则在用到这两个类加载器的地方都会用Common ClassLoader的实例代替,而默认的配置文件中没有设置这两个loader项,所以Tomcat 6.x
因此判断类是否完全相同,需要以下两个条件即:类的全路径名是否相同、加载类的类加载器是否为同一个,这两个条件决定类是否完全相同。...因此当自己在代码内部中编写恶意java代码时,比如HashMap文件,如果路径名相同,则会委派给父类Bootstrap ClassLoader进行加载,发现在Bootstrap加载的lib目录下存在HashMap...所以打破了双亲委派机制,并且在tomcat类加载器中也存在打破双亲委派机制的情况。...当tomcat中存在多个war包并同时使用了相同版本的jar包时,为了减少资源的浪费,可以使用该加载器,抽出这些相同版本的jar包,使用Shared ClassLoader加载一次被共享的jar即可,来代替每个...(4)委派tomcat中的父类CommonClassLoader是否加载过该类。 (5)当前WebAppClassLoader自己加载该类。 (6)如果类仍然没有加载成功,则抛出异常。
Java.lang.String 等核心类处于同一个包名下,那么此类就具有访问这些核心类 package 方法的权限,此外如果用户自定义一个 java.lang.String 类,如果类加载器加载了这个类...Test 类被加载前也看到了这些核心类被加载的原因 类加载都要遵循双亲委派机制吗 不是的,一个典型的应用场景就是 Tomcat 的类加载,由于 Tomcat 可能会加载多个 web 应用,而多个应用很有可能出现包名...绿色部分是 java 项目在打 war 包的时候, tomcat 自动生成的类加载器, 也就是说 , 每一个项目打成一个war包, tomcat都会自动生成一个类加载器, 专门用来加载这个 war...包,当加载 war 包中的类时,首先由 webappClassLoader 加载,而不是首先委托给上一级类加载器加载,这样的话由于加载每一个 war 包的 webappClassLoader 都不一样,...那么这个类是在字节码中是以符号引用的形式存在的,所以就要确保真正用到此类的时候能找到此类,如果找不到就会报错,举个简单的例子,假设有以下两个类,显然编译时都能通过,但在编译后如果我把 B.class 删掉
等 ▪ 扩展类加载器:负责加载支撑JVM运行的位于JRE的lib目录下的ext扩展目录中的JAR 类包 ▪ 应用程序类加载器:负责加载ClassPath路径下的类包,主要就是加载你自己写的那 些类 ▪...我们思考一下:Tomcat是个web容器, 那么它要解决什么问题: 一个web容器可能需要部署两个应用程序,不同的应用程序可能会依赖同一个第三方类库的不同版本,不能要求同一个类库在同一个服务器只有一份,...; ▪ catalinaLoader:Tomcat容器私有的类加载器,加载路径中的class对于Webapp不可见; ▪ sharedLoader:各个Webapp共享的类加载器,加载路径中的class...对于所有Webapp可见,但是对于Tomcat容器不可见; ▪ WebappClassLoader:各个Webapp私有的类加载器,加载路径中的class只对当前Webapp可见,比如加载war包里相关的类...模拟实现Tomcat的webappClassLoader加载自己war包应用内不同版本类实现相互共存与隔离 注意:同一个JVM内,两个相同包名和类名的类对象可以共存,因为他们的类加载器可以不一 样,所以看两个类对象是否是同一个
使用 java.lang.reflect 包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。...这样做是确保类只会被加载一次。通常我们的类加载器只识别 classpath (这里的 classpath 指项目根路径,也就是 jar 包内的位置)下 .class 文件。...tomcat 的类加载器: Common 类加载器:负责加载 /common 目录的类库,这儿存放的类库可被 tomcat 以及所有的应用使用。...我们将一堆 jar 包放到 tomcat 的项目文件夹下, tomcat 运行的时候能加载到这些 jar 包的 class 就是因为这些类加载器对读取到的二进制数据进行处理解析从中拿到了需要的类 SpringBoot...这样就实现了加载 jar 包中的 jar 这个功能否则正常的类加载器是无法加载 jar 包中的 jar 的 class 的,只会根据 MAINFEST.MF 来加载 jar 外部的 jar 来读取里面的
Tomcat负责加载我们的Servlet类、加载Servlet所依赖的JAR包。Tomcat本身也是个Java程序,因此它需要加载自己的类和依赖的JAR包。...所以Web应用之间的类需要隔离 若两个Web应用都依赖同一三方jar,比如Spring,则Spring jar被加载到内存后,Tomcat要保证这两个Web应用能共享之,即Spring jar只被加载一次...SharedClassLoader 两个Web应用之间怎么共享库类,并且不能重复加载相同的类? 双亲委派机制的各子加载器都能通过父加载器去加载类,于是考虑把需共享的类放到父加载器的加载路径。...CatalinaClassLoader 如何隔离Tomcat本身的类和Web应用的类? 兄弟关系:两个类加载器是平行的,它们可能拥有同一父加载器,但两个兄弟类加载器加载的类是隔离的。...线程上下文加载器 于是有了线程上下文加载器,一种类加载器传递机制。因为该类加载器保存在线程私有数据里,只要是同一个线程,一旦设置了线程上下文加载器,在线程后续执行过程中就能把这个类加载器取出来用。
一、加载: 通过一个类的全限定类名获取定义此类的二进制字节流 将这个字节流所代表的静态存储结构转化成方法区的运行时数据结构 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据访问入口...,因为final在编译的时候会分配,准备阶段会显式初始化 这里不会为实例变量分配初始化,类变量会分配在方法区中,而实例变量是会随着对象一起分配到Java堆中 解析 将常量池内的符号引用转换为直接引用的过程...如果类加载器还存在其父类加载器,则进一步向上委托,依次递归请求最终到达顶层的启动类加载器 如果父类加载器可以完成,就成功返回,如果类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派机制...优势: 避免重复加载 保护程序安全,防止核心API被随意修改 在JVM中标识两个class对象是否为同一个类存在两个必要条件: 类的完整类名必须一直,包括包名 加载这个类的ClassLoader...(指ClassLoader实例对象)必须相同 在JVM中,即使两个类对象来源同一个Class文件,被同一个虚拟机加载,但只要加载他们的ClassLoader实例对象不同,那么这两个类对象也是不相等的
JVM 运行实例中会存在多个 ClassLoader,不同的 ClassLoader 会从不同的地方加载字节码文件。...---- AppClassLoader AppClassLoader才是直接面向我们用户的加载器,它会加载 Classpath 环境变量里定义的路径中的 jar 包和目录。...我们知道Tomcat可以部署多个应用,不同的应用程序可能会依赖同一个第三方类库的不同版本,不能要求同一个类库在同一个服务器只有一份,因此要保证每个应用程序的类库都是独立的,保证相互隔离 ....部署在同一个web容器中相同的类库相同的版本可以共享, 比如jdk的核心jar包,否则,如果服务器有n个应用程序,那么要有n份相同的类库加载进虚拟机。...---- 常见错误 NoClassDefFoundError NoClassDefFoundError : 由于JVM或者类加载器实例尝试加载类型的定义,但是该定义却没有找到,影响了执行路径。
主流的Java Web服务器,如Tomcat、Jetty、WebLogic、WebSphere或其他笔者没有列举的服务器, 都实现了自己定义的类加载器,而且一般还都不止一个。...因为一个功能健全的Web服务器,都要解决 如下的这些问题: 部署在同一个服务器上的两个Web应用程序所使用的Java类库可以实现相互隔离。...(WebApp类加载器) 部署在同一个服务器上的两个Web应用程序所使用的Java类库可以互相共享。(Shared类加载器) 服务器需要尽可能地保证自身的安全不受部署的Web应用程序影响。...被放置到不同路径中的类库,具备不同的访问范围和服务对象,通常每一个目录都会有一个相应的自定义类加载器去加载放置在里面的Java类库。...和share.loader项后才会 真正建立Catalina类加载器和Shared类加载器的实例,否则会用到这两个类加载器的地方都会用 Common类加载器的实例代替,而默认的配置文件中并没有设置这两个
中却只有getXX(A) 4、在数据在运算中的神秘失踪,如方法A jar中有方法void A(B b),C包中调用A的方法传入的对象 b和Ajar中的B加载的是有类冲突的B。...部署在同一个tomcat下的项目使用的基础jar包要尽量统一,从制度和规范上解决这个问题。最好能一个公司统一的依赖库,maven是个不错的管理方式,公司按照统一的步调处理依赖项。...5、对于不能移除的可以通过控制jar包加载的顺序 6、确认不需要的jar包是否已经真从相关路径中移除。...个人就曾遇到从项目的依赖项中把jar去掉了,但是lib路径下仍存在这个jar导致的仍然被打到包里去了,活活郁闷两天。...这种加载机制也能给我带来便利性的一面。 比如我们要修改jar A中类B的实现,而我们又没有源代码,此时这种加载机制就很有用了。 我们只需要在项目的src中按照B的包名搭建即可。
如果在数组初始化时没有对数组中的各元素赋值,那么其中的元素将根据对应的数据类型而被赋予默认的零值 如果类字段的字段属性表中存在ConstantValue属性,即同时被final和static修饰,那么在准备阶段变量...一旦一个类被加载如JVM中,同一个类就不会被再次载入了。正如一个对象有一个唯一的标识一样,一个载入JVM的类也有一个唯一的标识。...例如,如果在pg的包中有一个名为Person的类,被类加载器ClassLoader的实例kl负责加载,则该Person类对应的Class对象在JVM中表示为(Person.pg.kl)。...的安装目录,下同)下,或被-Xbootclasspath参数指定的路径中的,并且能被虚拟机识别的类库(如rt.jar,所有的java....自定义类加载器 Custom ClassLoader:通过继承java.lang.ClassLoader根据自身需要自定义ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader
包的方法对类进行反射调用时,如果类没有进行过初始化,则需要先触发其初始化 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化 当虚拟机启动时,用户需要指定一个要执行的主类...举个例子: // 变量 value 在准备阶段过后的初始值为 0 而不是 123 public static int value = 123; 特殊情况:如果类字段的字段属性表中存在 ConstantValue...直接引用是与虚拟机实现地内存布局相关的,同一个符号引用在不同虚拟机实例上翻译出来的直接引用一般不会相同。如果有了直接引用,那引用的目标必定已经在内存中存在。...比较两个类是否 "相等" 只有在这两个类是由同一个类加载器加载的前提之下才有意义,否则,即使这两个类是来源于同一个 Class 文件,只要它们的类加载器不同,那这两个类就必定不相等。...不同的类加载器(Java 开发人员角度) 启动类加载器:与上述一致 负责将存放在 \lib 目录中的,或者被 -Xbootclasspath 参数所指定的路径中,并且是虚拟机识别的类库加载到虚拟机内存中
如果使用JDK默认的双亲委派模式,Tomcat的类加载器可以加载吗?我们思考一下Tomcat作为一个Web容器的使用场景。 在Web容器中,可能同时需要部署两个以上的应用程序。...一个典型的场景是不同的应用程序会依赖同一个第三方类库的不同版本,不能要求同一个类库在同一个服务器中只有一份,因此要保证每个应用程序的类库都是独立的,保证相互隔离。...Tomcat如果使用默认类加载器,是无法加载两个相同类库的不同版本的。...其中: ● Common ClassLoader:Tomcat最基本的类加载器,加载路径中的Class可以被Tomcat容器本身及各个WebApp访问。...● Catalina ClassLoader:Tomcat容器私有的类加载器,加载路径中的Class对于WebApp不可见。
类加载器分类Java虚拟机定义了三个主要类加载器:启动类加载器(Bootstrap Class Loader)负责将存放在\lib等目录中的,或者被-Xbootclasspath参数所指定的路径中的...,并且是虚拟机识别的(仅按照文件名,如rt.jar)类库加载到虚拟机内存中。...其他笔记同一个类尽量不要通过不同的类加载器加载,因为多个类加载器间可能时相互隔离的,如果类中存在类变量或者线程变量在使用时可能由于类加载器不一致导致数据异常。...运行过程中如果需要动态加载多个类,需要注意按需卸载避免内存溢出。Tomcat实现的自定义类加载器在不同webapp之间会创建不同的类加载实例,他们加载的应用类是隔离的,不完全遵循双亲委派模型。...比如:通过javaagent对Serverlet进行拦截,那这个对同一个Tomcat下所有webapp都生效的。
包将类的命名空间进行有效划分,同一包中不能有两个同名的类. Java 系统提供的类库也成为Java API, 是系统提供的已实现的标准类的集合。...建立包 创建包就是在指定目录路径下创建一个子文件夹,这个包中所有类的字节码文件将存放在该文件夹下。...编译后将在当前目录自动创建 test 子目录 包的引用 同一个包下的类之间互相引用是不需要包名的,可以直接使用。但如果类不在同一个包内,则必须要知道其所在的包。...例: import java.util.Date; 然后在程序中可以直接通过类名创建对象, 如:new Date(); 用 import 语句加载整个包, 用*号代替类名位置。...总结来说,import 是编译时概念,用于确定完全限定名,在运行时,只根据完全限定名寻找并加载类,编译和运行时都依赖类路径,类路径中的 jar 文件会被解压缩用于寻找和加载类。
Tomcat进阶篇 一、聊聊ClassLoader的那些事儿 我们要分析清楚Tomcat中的类加载器相关的内容之前我们还是需要把JVM中的类加载器给大家理清楚。...在Web容器中我们应该要满足如下的特性: 隔离性: 部署在同一个Web容器上的两个Web应用程序所使用的Java类库可以实现相互隔离。...如果采用一个类加载器,类之间的依赖是杂乱复杂的,无法完全移出某个应用的类。 性能: 性能也是一个比较重要的点。部署在同一个Web容器上的两个Web应用程序所使用的Java类库可以互相共享。.../catalina.properties中配置,具体介绍下: Common:以应用类加载器为父类,是tomcat顶层的公用类加载器,其路径由conf/catalina.properties中的common.loader...首先,Common类加载器复杂加载Tomcat应用服务器内部和Web应用均可见的类,如Servlet规范相关包和一些通用工具包。
领取专属 10元无门槛券
手把手带您无忧上云