深入理解Java虛擬機----(八)類加載和執行子系統的應用
在上一篇class文件和執行引擎這部分中,用戶能參與的部分不是太多。class格式、加載、鏈接、解釋執行都是虛擬機規定的,能通過程序操作的有:類加載器和字節碼生成。下面看看幾個相關的精彩案例:
Tomcat的加載器架構
javaweb服務器通常有多個自定義類,來解決這些問題
- 不同web項目間的類庫隔離
- 不同web項目間類庫的共享
- java編寫的服務器本身和項目類庫間的隔離,保證安全 Tomcat中,四個目錄可以存放類庫:
- /common 可以被tomcat和所有web項目共享
- /server 只能被tomcat使用
- /shared tomcat 不可見,能被web項目共享
- 項目的/WebApp/WEB-INF 當前web項目自己可見 為了實現這些目的,Tomcat定義了多個類加載器,都是按照雙親委派模型實現的,如圖
上面灰色的三個是JDK提供的。按照雙親委派模型的規則,很清晰的看到這個架構是怎麼實現上面說的目標的。其中WebApp類加載器可能有多個,一個web項目一個;Jsp類加載器也有多個,一個JSP文件一個,它的出現是為了被丟棄:當JSP文件發生變動時,丟棄它並新建一個加載器替換它,實現JSP文件的HotSwap功能。
OSGI的類加載架構
OSGI的加載器模型不再是簡單樹形模型,而是更為復雜的、運行時確定的網狀模型。
它的這種加載器間的關系只是一種概念上的依賴關系,例如模塊A依賴模塊B,模塊B發布了自己為B。運行時模塊A發現依賴了B,僅在找到了發布B的模塊之後,將依賴的加載任務交給發布B的模塊的加載器。
字節碼生成和動態代理
Java中有很多字節碼生成的類庫,javac就是最為原始的一個。動態代理就是一個相對簡單的應用。動態代理相比靜態代理而言,優勢不是在於少些的那點代碼,而是在原始類和接口未知的時候就確定了代理的內容。當原始和代理脫離關系後,代理就可以被靈活的用到各種場景中!
其實質就是按照字節碼格式和規則拼裝字節碼,最終被類加載器加載,然後實例化成對象使用。