tomcat jar包编译后变成文件夹_tomcat学习|tomcat中的类加载器
開(kāi)頭說(shuō)兩句
小刀博客: https://www.lixiang.red
小刀公眾號(hào): 程序員學(xué)習(xí)大本營(yíng)
學(xué)習(xí)背景
上期我們聊到了tomcat中各個(gè)組件在默認(rèn)值,在其中,我們看到了有關(guān)類加載器的代碼, 如context中初始化wabAppLoader https://www.lixiang.red/articles/2019/08/09/1565361802994.html 今天我們一起學(xué)習(xí)類加載器相關(guān)知識(shí)
java里面的類加載器
我們?cè)趯慾ava代碼時(shí),源文件是 .java , 然后經(jīng)過(guò)編譯之后,會(huì)變成 .class 文件,類加載器加載的,實(shí)際上就是*.class文件, 在實(shí)際開(kāi)發(fā)中,我們會(huì)把相關(guān)的 .class 文件,打成一個(gè)jar包, 然后直接加載jar包就可以了. 類加載器就是用來(lái)加載這些類到虛擬機(jī)里,供程序調(diào)用
Bootstrap Class Loader
用來(lái)加載JVM提供的基礎(chǔ)運(yùn)行類,即位于%JAVA_HOME%jre/lib 這個(gè)目錄下面的核心類庫(kù)
Extension Class Loader
java提供的一個(gè)標(biāo)準(zhǔn)備的擴(kuò)展機(jī)制,用于加載除核心類庫(kù)外的jar包.默認(rèn)的擴(kuò)展目錄是 %JAVA_HOME%/jar/lib/ext
該目錄下的類庫(kù),對(duì)所有基于該JVM運(yùn)行的程序都是可見(jiàn)的
System class loader
用于加載環(huán)境變量 CLASSPATH 指定目錄下的或者是用 -classpath運(yùn)行參數(shù)指定的jar包.
System Class Loader 通常用于加載應(yīng)用程序jar包及其啟動(dòng)入口類(Tomcat Bootstrap類就是由System Class Loader 來(lái)加載的)
類加載器的雙親委派模式
上面三種類加載器,實(shí)際上是有父子關(guān)系,Bootstrap 是 Extension的父加載器, Extension 是System的父加載器 當(dāng)System ClassLoader 拿到一個(gè)class 文件之后, 會(huì)先問(wèn)父加載器(Extension Class Loader)能不能加載,當(dāng)(Extension )接收到請(qǐng)求時(shí),會(huì)先問(wèn)問(wèn)他的父加載器(BootStrap類加載器能不能加載). 如果 Bootstrap可以加載,則由Bootstrap來(lái)加載,如不能,則由Extension來(lái)加載. 如果 Extension 也加載不了的話,最后由System 類加載器來(lái)加載.
tomcat中的類加載器
總共有四種類加載器: Common Class Loader, Catalina Class Loader , Shared Class Loader, Web AppClass Loader. tomcat中各個(gè)類加載器初始化,聲明的地方
/*** 初始化tomcat中的三大類加載器*/private void initClassLoaders() {try {// CommonLoader 默認(rèn)繼承AppClassLoadercommonLoader = createClassLoader("common", null);if( commonLoader == null ) {// no config file, default to this loader - we might be in a 'single' env.commonLoader=this.getClass().getClassLoader();}// 以CommonLoader 為父加載器catalinaLoader = createClassLoader("server", commonLoader);// 以CommonLoader 為父加載器sharedLoader = createClassLoader("shared", commonLoader);} catch (Throwable t) {handleThrowable(t);log.error("Class loader creation threw exception", t);System.exit(1);}}Common Class loader
以System Class Loader 為父類加載器, 是位于Tomcat 應(yīng)用服務(wù)器頂層的公用類加載器,默認(rèn)是加載$CATALINE_HOME/lib 下的jar 包
Catalina Class Loader
以Common Class Loader 為父加載器.用于加載 Tomcat 應(yīng)用服務(wù)器本身的.可以在下圖中看到使用的位置 1.設(shè)置當(dāng)前線程的類加載器為Catalina Class Loader , 在沒(méi)設(shè)置之前,是由 shell 腳本用 System Class Loader 來(lái)加載的 2. 用Catalina Class Loader 加載 Catalina.class 這個(gè)文件,并完成一系統(tǒng)組件的初始化
shared Class Loader
以Common 為父加載器,是所有web應(yīng)用的父加載器 使用位置如下:
/*** Set the shared extensions class loader.** @param parentClassLoader The shared extensions class loader.*/public void setParentClassLoader(ClassLoader parentClassLoader) {this.parentClassLoader = parentClassLoader;}在源碼中聲明parentClassLoader時(shí)有一個(gè)小坑,他默認(rèn)是聲明的加載Catalina的類載器即:Catalina Class Loader,但實(shí)際上,在實(shí)例化后,我們會(huì)用反射調(diào)用其setParentClassLoader 方法,將parentClassLoader 更改為shared Class Loader
// XXX Should be moved to embedded/*** The shared extensions class loader for this server.*/protected ClassLoader parentClassLoader =Catalina.class.getClassLoader();使用地點(diǎn):
WebApp Class Loader
初始化的地點(diǎn)有兩處: 1.createStartDigester中
digester.addObjectCreate(prefix + "Context/Loader","org.apache.catalina.loader.WebappLoader","className");其作用是,每個(gè)獨(dú)立的Context(web應(yīng)用)都使用獨(dú)立的ClassLoader,加載我們web應(yīng)用中,WEB-INFO/libs 這個(gè)目錄下的jar(如我們?cè)趹?yīng)用中引用的spring , mybatis 這些包) 這個(gè)做的好處是,不同的web應(yīng)用包不會(huì)沖突,如A應(yīng)用用的是spring 4.X , B應(yīng)用用的是spring 5.X , 他們可以在同一個(gè)tomcat中運(yùn)行
最后說(shuō)兩句
tomcat的類加載機(jī)制, 是開(kāi)始的一個(gè)比較復(fù)雜的點(diǎn),需要好好理一理,邊看代碼邊做筆記,這個(gè)類加載器什么時(shí)候初始化的,做了什么,然后在哪里使用的. 大家在學(xué)習(xí)過(guò)種中,有什么問(wèn)題,可以和小刀一起交流討論: best396975802
總結(jié)
以上是生活随笔為你收集整理的tomcat jar包编译后变成文件夹_tomcat学习|tomcat中的类加载器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 全民k歌附近的人怎么打招呼
- 下一篇: 事态升级是什么意思_第602期搞笑gif