天天看點

類加載器,雙親委派機制,Tomcat打破雙親委派

前言

        最近嘗試手寫一個簡單的Tomcat,但在類加載這一塊有點模糊,,于是有了下面的猜想:

       java項目是如何被加載已經如何被執行的,,通過資料得知靠的是loader子產品,并且tomcat與Java項目共享同一JVM資源(現需要了解JVM,目前猜想:Tomcat與java項目可以看作同一個Java項目,一起加載進JVM中,,Tomcat與Java項目可以互相調用)

        後面去了解了類加載器後發現猜想出錯了,如果Tomcat的依賴包與Java項目沒有存在依賴沖突,我的猜想還能接受,但是真的把看作一個項目是會出問題的,而Tomcat的做法很好的解決了這個問題。

類加載器

      因為沒有過多的了解類加載器,導緻了了解上的偏差,是以先要了解類加載器:類加載器分為三種:bootstrapclassloader,extclassloader,appclassloader,除此之外還可以自定義類加器:你可以繼承classloader類,重寫核心方法來實作自己的類加載器,隻能說java的設計者在對靈活性與擴充性方面做的真的很好,這些都考慮到了,是以類加載器并沒有封裝到JVM内部,而是在外部實作的,并且可供開發者自行設計。

雙親委派與打破雙親委派

       提到類加載器,就不得不提裡面的一個重要機制:雙親委派機制,它的實作其實并不複雜你可以檢視classloader類的源碼,裡面就能看到雙親委派機制實作代碼,用簡單的邏輯解決了類加載重複,以及可能會被開發者篡改源碼的風險這兩大問題,膜拜大佬,下面是雙親委派機制源碼:

1.入口

類加載器,雙親委派機制,Tomcat打破雙親委派

2.實作雙親委派

類加載器,雙親委派機制,Tomcat打破雙親委派
類加載器,雙親委派機制,Tomcat打破雙親委派

        雖然雙親委派設計很好,可是也得根據實際情況,而tomcat是一個web伺服器,它可能需要部署多個應用,那麼每個應用都會有各自的依賴,如果是相同jar包的不同版本,這時,雙親委派就成了問題的原因,這個時候就需要打破雙親委派,如何打破?實作自己的類加載器,jvm識别不同的類靠的是全限定類名與類加器,不同的類加載器加載的類必定不相同,比如:Java的核心類庫:Integer,如果自己寫一個一模一樣的,jvm會用嗎?那必不會,因為雙親委派機制的存在,它會發現String類已經由bootstrapclassloader加載器加載過了,而自己編寫的代碼是由appclassloader加載的,雙親委派決定了父類的優先級更高,而且這個雙親委派用Java是無法打破的,因為它不是由java語言編寫,由C/C++編寫。通過實作自定義類加載器,打破了雙親委派機制,實作了應用間的依賴隔離,但是,需要打破全部雙親委派嗎?比如一些共有的依賴,所有web程式都會共用的依賴也需要打破嗎?除了bootstrapclassloader無法打破之外,可能還會存在一些需要共用的依賴可以不打破。但是雙親委派的設計是毋庸置疑的,任何設計都不可能做到十全十美。