Tomcat source analysis (with class loading class loader)

Tomcat challenge

Tomcat can be deployed on multiple projects

Tomcat general deployment, through a variety of ways to start a Tomcat deploy multiple projects, then Tomcat will confront the challenges in the design of it?

Tomcat which classes need to be loaded runtime

Tomcat plurality of items of the same class may exist

Tomcat class loader challenges

Source code analysis thoroughly understand Tomcat classloading

And a class loader to load the class

Class loader

Class loading: mainly the .class file is read into binary byte JVM in

We can see that because of this definition, it does not require a disk must be to load a file, you can network, memory or something loaded. As long as the binary stream of data bytes, the JVM will recognize.

Class loading process:

1. the fully qualified name of the class by class acquired binary byte stream;

2. The static structure represented by the byte stream into run-time data structure area method

3. generates a class in memory java.lang.Class objects, as a method for accessing data in various regions of the class entry

Class loader

Defined: the JVM designers to " class loader " This action put java external virtual machine to achieve, to allow the application to decide how to get the required categories. To achieve this module the operation code " class loader "

Class and class loader

For any of the classes, which are determined by the need to load its class and the class loader JVM uniqueness of. That is, both from the same class a Class file, and loaded with a class loader, these two classes are equal.

Note: This so-called "equal", the general use instanceof keyword to make a judgment.

Class loader delegation model with parents

Class loader

Start class loader: The loader uses the C ++ language, is part of the virtual machine itself.

Start class loader ( Bootstrap ClassLoader ) : responsible for loading the JAVA_HOME \ lib directory and can be recognized by the virtual machine library is loaded into JVM memory, if the name does not meet even in the library lib it will not be loaded catalog. This class loader can not be java directly referenced

Expand the application class loader class loader: Another part is that all other class loader, the class loader is a Java implementation language, independent of the JVM outside, and all inherited abstract class java.lang.ClassLoader .

Extension class loader (Extension ClassLoader): The loader is responsible for loading JAVA_HOME \ lib \ ext directory of libraries, developers can use the extended loader.

Application class loader ( the Application ClassLoader ) : This column is also referred loader system loader, which is responsible for loading the user class path (the Classpath) on the specified library, developers can use the class loader directly, if the application none had their own custom class loader, in general, this program is the default class loader

Parent delegation model

Definition: parents delegate the work process model is as follows: if a class loader class received a request, it does not own to try to load this class, but to delegate this request to the parent loader to complete each level is so , so all requests will be passed to the class loader to start class loader, loader only when the parent can not complete the request, the only sub-loader to load their own.

Implementation: The model requires that in addition to the top of the boot class loader, the rest of the class loader should have its own parent class loader. Loader is not a subclass to inherit the relationships to achieve, but the parent code with the multiplexed by combining relationship loader.

Meaning: the benefits of parents to delegate the benefits of the model is that java class as it has class loader together with a priority hierarchy. For example: Object, regardless of the class loader to load the class are ultimately loaded by the boot class loader, so the Object class in various types of programs are loaded in a class environment. If you do not change the model, then the java.lang.Object class stored in the classpath , then the system will be more Object class, the program has become very confusing.

Parent delegation model

    From the perspective of the virtual machine, there are two different class loader: one is the boot class loader ( on Bootstrap ClassLoader ) , the loader uses the C ++ language, part of the virtual machine itself. Another part is that all other class loader, the class loader is a Java implementation language, independent of the JVM outside, and all inherited abstract class java.lang.ClassLoader.

    From java developer point of view, most of the java program will use the following three class loader provided by the system:

    1 , start the class loader ( Bootstrap ClassLoader ) : responsible for loading the JAVA_HOME \ lib directory and can be recognized by the virtual machine library is loaded into JVM memory, if the name does not meet even in the library lib will not be loaded directory . This class loader can not be java directly referenced.

    2 , the extension class loader (Extension ClassLoader): The loader is responsible for loading JAVA_HOME \ lib \ ext directory of libraries, developers can use the extended loader.  

     3 , application class loader ( the Application ClassLoader ) : This column is also referred loader system loader, which is responsible for loading the user class path (the Classpath) on the specified library, developers can directly use the class loader, if no custom application had its own class loaders, in general, this program is the default class loader.

JVM class loader source Analysis

AppClassLoader

 

 

 

URLClassLoader

 

 

SecureClassLoader

 

 

Tomcat in the class loading solution

Tomcat class loading considerations

Isolation

Web应用类库相互隔离,避免依赖库或者应用包相互影响,比如有两个Web应用,一个采用了Spring 4,一个采用了Spring 5,而如果如果采用同一个类加载器,那么Web应用将会由于jar包覆盖而无法启动成功。

 

 

 

 

灵活性

因为隔离性,所以Web应用之间的类加载器相互独立,如果一个Web应用重新部署时,该应用的类加载器重新加载,同时不会影响其他web应用

比如:不需要重启Tomcat的创建xml文件的类加载,

还有context元素中的reloadable字段:如果设置为true的话,Tomcat将检测该项目是否变更,当检测到变更时,自动重新加载Web应用。

性能

由于每一个Web应用都有一个类加载器,所以在Web应用在加载类时,不会搜索其他Web应用包含的Jar包,性能自然高于只有一个类加载的情况。

 

Tomcat中的类加载器

Tomcat提供3个基础类加载器(commoncatalinashared)和Web应用类加载器。

 

 

 

 

Tomcat中的类加载源码分析

三个基础类加载器

介绍

3个基础类加载器的加载路径在catalina.properties配置,默认情况下,3个基础类加载器的实例都是一个。

createClassLoader调用ClassLoaderFactory属于一种工厂模式,并且都是使用URLClassLoader

 

 

 

 

 

默认情况三个是一个实例,但是可以通过修改配置创建3个不同的类加载机制,使它们各司其职。

举个例子:如果我们不想实现自己的会话存储方案,并且这个方案依赖了一些第三方包,我们不希望这些包对Web应用可见,因此我们可以配置server.loader,创建独立的Catalina类加载器。

共享性:

Tomcat通过Common类加载器实现了Jar包在应用服务器与Web应用之间的共享,

通过Shared类加载器实现了Jar包在Web应用之间的共享

通过Catalina类加载器加载服务器依赖的类。

 

 

类加载工厂

因为类加载需要做很多事情,比如读取字节数组、验证、解析、初始化等。而Java提供的URLClassLoader类能够方便的将JarClass或者网络资源加载到内存中。而Tomcat中则用一个工厂类,ClassLoaderFactory把创建类加载器的细节进行封装,可以通过它方便的创建自定义类加载器。

 

 

 

 

 

 

 

 

 

 

 

 

使用加载器工厂的好处

  1. ClassLoadFactory有一个内部Repository,它就是表示资源的类,资源的类型用一个RepositoryType的枚举表示。
  2. 同时我们看到,如果在检查jar包的时候,如果有检查的URL地址的如果检查有异常就忽略掉,可以确保部分类加载正确。

 

尽早设置线程上下文类加载器

 

 

每一个运行线程中有一个成员ContextClassLoader,用于在运行时动态载入其他类,当程序中没有显示声明由哪个类加载器去加载哪个类(比如new出一个类时),将默认由当前线程类加载器加载,所以一般系统默认的ContextClassLoad是系统类加载器。

一般在实际的系统上,使用线程上下文类加载器,可以设置不同的加载方式,这个也是Java灵活的类加载方式的体现,也可以很轻松的打破双亲委派模式,同时也会避免类加载的异常。

Webapp类加载器

每个web应用会对一个Context节点,在JVM中就会对应一个org.apache.catalina.core.StandardContext对象,而每一个StandardContext对象内部都一个加载器实例loader实例变量。这个loader实际上是WebappLoader对象。而每一个 WebappLoader 对象内部关联了一个 classLoader 变量(就这这个类的定义中,可以看到该变量的类型是org.apache.catalina.loader.WebappClassLoader)。

所以,这里一个web应用会对应一个StandardContext 一个WebappLoader 一个WebappClassLoader

一个web应用对应着一个StandardContext实例,每个web应用都拥有独立web应用类加载器(WebappClassLoader),这个类加载器在StandardContext.startInternal()中被构造了出来

 

 

 

 

注意这里:设置加载器和获取加载器都使用了读写锁机制,确保多线程情况下对共享资源的访问不会出现问题。

同时因为Tomcat的生命周期管理,必定会调用WebappLoader.javastartInternal()方法,该方法中new出了

 

 

 

所以总结一句话,如果没有弄懂Tomcat的启动流程,以及弄懂Tomcat的生命周期的管理,很多地方的源码是没有办法没有看懂,所以看源码也有一个先后顺序。

热加载源码分析

当配置信息中有reloadable的属性,并且值为true时,Tomcat怎么去完成这个过程呢?

 

 

还是看源码,据Tomcat的启动流程,我们分析下Context的初始化start方法,根据之前的课程我们可知道,Context只是一个接口,具体实现类是StandardContext,我们分析下startInternal方法(此方法由之前的抽闲骨架类中的start方法触发)

 

 

我发现有一个线程启动的方法 threadStart(),

 

 

由上图我们知道,这个是父类中调用,

 

 

 

 

 

 

 

 

Guess you like

Origin www.cnblogs.com/Soy-technology/p/11241799.html