web容器類載入順序
Weblogic中classloader是分層次的,它只能載入比它層次高的類及它自身的類,同層次的類及比它層次低的類都不能載入。
在weblogic中的classloader有5個層次,從高到低排:
a. jdk
b. jdk ext
c. system classpath
d. ( APP-INF/classes and APP-INF/lib )
e. ( WEB-INF/classes and WEB-INF/lib )
注意:這裡是先載入classes中的類,再載入lib中的類, 若要修改它的載入順序,可以通過在Weblogic.xml(版本為8)中加入以下程式碼:
<container-descriptor>
<prefer-web-inf-classes> true </prefer-web-inf-classes>
</container-descriptor>
f. ejb.jar
注意:e 和 f 的classloader是同級的。
所以APP-INF/lib和APP-INF/classes下類不能例項化webapp下的類,這點尤其要注意,否則會報類找不到的錯誤。
來自Weblogic官方的說明檔案中,對於Weblogic的類載入順序給出了一個比較清晰和簡單的描述:
當部署一個應用的時候,weblogic server會自動建立一個具有層次結構的類裝載器。
1、a.Application Classloader負責裝載應用中的所有的EJB JAR檔案;
2、b.Web Application Classloader負責裝載所有的Web application 中的WAR 檔案(所有得jsp檔案除外);
3、c.Jsp Classloader 負責裝載Web application 中的所有的jsp 檔案。
Tomcat與Weblogic是相反的:對於執行在 Java EE 容器中的 Web 應用來說,類載入器的實現方式與一般的 Java 應用有所不同。不同的 Web 容器的實現方式也會有所不同。以 Apache Tomcat 來說,每個 Web 應用都有一個對應的類載入器例項。該類載入器也使用代理模式,所不同的是它是首先嚐試去載入某個類,如果找不到再代理給父類載入器。這與一般類載入器的順序是相反的。這是 Java Servlet 規範中的推薦做法,其目的是使得 Web 應用自己的類的優先順序高於 Web
容器提供的類。這種代理模式的一個例外是:Java 核心庫的類是不在查詢範圍之內的。這也是為了保證 Java 核心庫的型別安全。
附:java類載入順序
java類裝載器
Java中的類裝載器實質上也是類,功能是把類載入jvm中,值得注意的是jvm的類裝載器並不是一個,而是三個,層次結構如下:
Bootstrap Loader - 負責載入系統類
|
- - ExtClassLoader - 負責載入擴充套件類
|
- - AppClassLoader - 負責載入應用類
為什麼要有三個類載入器,一方面是分工,各自負責各自的區塊,另一方面為了實現委託模型,下面會談到該模型
類載入器之間是如何協調工作的
前面說了,java中有三個類載入器,問題就來了,碰到一個類需要載入時,它們之間是如何協調工作的,即java是如何區分一個類該由哪個類載入器來完成呢。
在這裡java採用了委託模型機制,這個機制簡單來講,就是“類裝載器有載入類的需求時,會先請示其Parent使用其搜尋路徑幫忙載入,如果Parent 找不到,那麼才由自己依照自己的搜尋路徑搜尋類”,注意喔,這句話具有遞迴性。
下面舉一個例子來說明,為了更好的理解,先弄清楚幾行程式碼:
Public class Test{
Public static void main(String[] arg){
ClassLoader c = Test.class.getClassLoader(); //獲取Test類的類載入器
System.out.println(c);
ClassLoader c1 = c.getParent(); //獲取c這個類載入器的父類載入器
System.out.println(c1);
ClassLoader c2 = c1.getParent();//獲取c1這個類載入器的父類載入器
System.out.println(c2);
}
}
把以上程式碼存到d:\my 資料夾下,直接編譯,然後在dos模式下執行
D:\my\java Test
。。。AppClassLoader。。。
。。。ExtClassLoader。。。
Null
D:\my
注: 。。。表示省略了內容
可以看出Test是由AppClassLoader載入器載入的
AppClassLoader的Parent 載入器是 ExtClassLoader
但是ExtClassLoader的Parent為 null 是怎麼回事呵,朋友們留意的話,前面有提到Bootstrap Loader是用C++語言寫的,依java的觀點來看,邏輯上並不存在Bootstrap Loader的類實體,所以在java程式程式碼裡試圖打印出其內容時,我們就會看到輸出為null。
弄明白了上面的示例,接下來直接進入類裝載的委託模型例項,寫兩個檔案,如下:
檔案:Test1.java
Public class Test1{
Public static void main(String[] arg){
System.out.println(Test1.class.getClassLoader());
Test2 t2 = new Test2();
T2.print();
}
}
檔案: Test2.java
Public class Test2{
Public void prin(){
System.out.println(this.getClass().getClassLoader());
}
}
這兩個類的作用就是打印出載入它們的類裝載器是誰, 將這兩個檔案儲存到d:\my目錄下,編譯後,我們在複製兩份,分別置於jdk1.4\jre\classes下(注意,剛開始我們的系統下沒有此目錄,需自己建立) 與 jdk1.4\jre\lib\ext\classes下(同樣注意,開始我們的系統下也沒此目錄,手工建立), 然後切換到d:\my目錄下開始測試,
測試一:
<JRE所在目錄>\classes下
Test1.class
Test2.class
<JRE所在目錄>\lib\ext\classes下
Test1.class
Test2.class
D:\my下
Test1.class
Test2.class
dos下輸入執行命令,結果如下:
D:\my>java Test1
Null
Null
D:\my>
從輸出結果我們可以看出,當AppClassLoader要載入Test1.class時,先請其Parent,也就是ExtClassLoader來載入,而ExtclassLoader又請求其Parent,即Bootstrap Loader來載入Test1.class. 由於 <JRE所在目錄>\Classes目錄為Bootstrap Loader的搜尋路徑之一,所以Bootstrap Loader找到了Test1.class,因此將它載入,接著在Test1.class之內有載入Test2.class的需求,由於Test1.class是由Bootstrap
Loader所載入,所以Test2.class內定是由Bootstrap Loader根據其搜尋路徑來找,因Test2.class也位於Bootstrap Loader可以找到的路徑下,所以也被載入了,最後我們看到Test1.class與Test2.class都是由Bootstrap Loader(null)載入。
測試二:
<JRE所在目錄>\classes下
Test1.class
<JRE所在目錄>\lib\ext\classes下
Test1.class
Test2.class
D:\my下
Test1.class
Test2.class
dos下輸入執行命令,結果如下:
D:\my>java Test1
Null
Exception in thread “main” java.lang.NoClassdefFoundError:Test2 at Test1.main。。。
D:\my>
從輸出結果我們可以看出,當AppClassLoader要載入Test1.class時,先請其Parent,也就是ExtClassLoader來載入,而ExtclassLoader又請求其Parent,即Bootstrap Loader來載入Test1.class. 由於 <JRE所在目錄>\Classes目錄為Bootstrap Loader的搜尋路徑之一,所以Bootstrap Loader找到了Test1.class,因此將它載入,接著在Test1.class之內有載入Test2.class的需求,由於Test1.class是由Bootstrap Loader所載入,所以Test2.class內定是由Bootstrap Loader根據其搜尋路徑來找,但是因為Bootstrap Loader根本找不到Test2.class(被我們刪除了),而Bootstrap Loader又沒有Parent,所以無法載入Test2.class.最後我們看到Test1.class是由Bootstrap Loader(null)載入,而Test2.class則無法載入
測試三
<JRE所在目錄>\classes下
Test2.class
<JRE所在目錄>\lib\ext\classes下
Test1.class
Test2.class
D:\my下
Test1.class
Test2.class
dos下輸入執行命令,結果如下:
D:\my>java Test1
。。。ExtClassLoader。。。
Null
D:\my>
從輸出結果我們可以看出,當AppClassLoader要載入Test1.class時,先請其Parent,也就是ExtClassLoader來載入,而ExtclassLoader又請求其Parent,即Bootstrap Loader來載入Test1.class.但是Bootstrap Loader無法在其搜尋路徑下找到Test1.class(被我們刪掉了),所以ExtClassLoader只得自己搜尋,因此ExtClassLoader在其搜尋路徑 <JRE所在目錄>\lib\ext\classes下找到了Test1.class,因此將它載入,接著在Test1.class之內有載入Test2.class的需求,由於Test1.class是由ExtClassLoader所載入,所以Test2.class內定是由ExtClassLoader根據其搜尋路徑來找,但是因為ExtClassLoader有Parent,所以先由Bootstrap Loader幫忙尋找,Test2.class位於Bootstrap Loader可以找到的路徑下,所以被Bootstrap Loader載入了.最後我們看到Test1.class是由ExtClassLoader載入,而Test2.class則是由Bootstrap Loader(null)載入
最後,總結一下,在Weblogic服務啟動的過程中,自動形成一個具有層次結構的類裝載器,首先裝載jdk及java擴充套件jar包或類;然後再載入Weblogic本身使用的各個jar包或類;然後再載入Web應用資料夾裡面的classes下的類,然後再載入Web應用資料夾裡面lib下的jar包或類。也就是說,每個層次的類裝載器均對應不同的類路徑,它們是一一對應的。 比如System裝載器對應著jdk及擴充套件路徑;Application裝載器對應著Weblogic的相關類;而web 應用裝載器對應著webapp應用下的classes和lib下的路徑;而jsp裝載器則對應著jsp檔案。
當然,在載入過程中,若在高層次的載入器中已經載入了某類,那麼再以後的載入中,再次遇到該類也不會載入,只是會忽略。載入完成之後,將類放入Cache中供系統應用呼叫。
在系統的執行過程中,若遇到使用該類的情況,則會遵循先通過其父類載入器進行載入的原則,比方說,我要載入一個WSWordManager類,
則系統會首先在Cache中尋找,若找不到,則呼叫父裝載器到與之對應的路徑裡面去尋找,一直向上,找著了則進行載入,若找不著則報出ClassNotFound的異常。
理解為:
1. weblogic會一次性裝載所有類,從上層到下層依次裝載所以上層不能例項化下層的類。
2. java會請示其Parent使用其搜尋路徑幫忙載入,如果Parent 找不到,那麼才由自己依照自己的搜尋路徑搜尋類
3.tomcat會從自己的搜尋路徑中搜索類,找不到再請示器parent
相關推薦
web容器類載入順序
Weblogic中classloader是分層次的,它只能載入比它層次高的類及它自身的類,同層次的類及比它層次低的類都不能載入。 在weblogic中的classloader有5個層次,從高到低排: a. jdk b. jdk ext c. system classpa
web.xml檔案載入順序 一、 1 、啟動一個 WEB 專案的時候, WEB 容器會去讀取它的配置檔案 web.xml ,讀取 和
web.xml 中的listener、 filter、servlet 載入順序及其詳解 一、概述 1、啟動一個WEB專案的時候,WEB容器會去讀取它的配置檔案web.xml,讀取<listener>和<context-param>兩個結點。
web.xml檔案載入順序
web.xml 中的listener、 filter、servlet 載入順序及其詳解 一、概述 1、啟動一個WEB專案的時候,WEB容器會去讀取它的配置檔案web.xml,讀取<listener>和<context-param>兩個結點。 2、緊急著
web.xml的載入順序和過程
Web.xml配置詳解之context-param <context-param> <param-name>contextConfigLocation</param-name> <param-value>contextConfigLocat
Java類載入順序問題
測試java程式碼塊中靜態塊,初始塊,構造塊的執行順序。 定義三個類A,B,C,B繼承於A,C繼承於B。 程式碼如下: package 類載入問題; public class A { static{ System.out.print("A類靜態塊1 "); } { Sys
使用@Order註解調整配置類載入順序
1 、@Order 1、Spring 4.2 利用@Order控制配置類的載入順序, 2、Spring在載入Bean的時候,有用到order註解。 3、通過@Order指定執行順序,值越小,越先執行 &
類載入順序說明
在 Java 中,Class<T> 和 ClassLoader 是造物之始。 萬物皆是“某類T” 的存在物,而“某類T” 是“萬類之類 Class<T>” 的存在物,類別也是一種存在物,存在物即 Object。 例項 t -> 類別 T -&
初探spring applicationContext在web容器中載入過程
首先從WEB.XML入手 ==>web.xml <context-param> <param-name>webAppRootKey</param-nam
Java中static關鍵字解析以及類載入順序例題
一.static關鍵字的用途 在《Java程式設計思想》P86頁有這樣一段話: “static方法就是沒有this的方法。在static方法內部不能呼叫非靜態方法,反過來是可以的。而且可以在沒有建立任何物件的前提下,僅僅通過類本身來呼叫static方法
Tomcat6類載入器定義(class類載入順序)
Class Loader Definitions As indicated in the diagram above, Tomcat 6 creates the following class loaders as it is initialized: (譯:就像上面
Java相同全限定名的類載入順序
相同的類指:類的全限定名一樣 問題: 怎麼優先載入自己寫的類 1. 解析: class檔案所在位置, 直接在classpath下, 在jar包中 a: 相同的類, 一個在web-inf/classes目錄下, 一個在jar包中: 此時優先載入classes目錄下
Java靜態程式碼塊和靜態方法的區別/類載入順序
(一)java 靜態程式碼塊 靜態方法區別 一般情況下,如果有些程式碼必須在專案啟動的時候就執行的時候,需要使用靜態程式碼塊,這種程式碼是主動執行的;需要在專案啟動的時候就初始化,在不建立物件的情況下,其他程式來呼叫的時候,需要使用靜態方法,這種程式碼是被動執行的.
Web容器的載入過程
(一)過程1.0啟動web專案的時候。 web容器讀取web.xml檔案,<listener>和<context-param>兩個節點。2.0 接著,容器建立一個ServletContext(sevlet上下文),這個web專案的所有部分都將共享這個
java複習一 ——java web專案啟動載入順序
web.xml載入過程(步驟): 1.啟動WEB專案的時候,容器(如:Tomcat)會去讀它的配置檔案web.xml.讀兩個節點: <listener></listener> 和 <context-param&g
Tomcat目錄結構以及類載入順序
Tomcat是一個優秀的Servlet容器,本身使用java語言編寫。Tomcat是Apache開源軟體組織的一個軟體專案。Tomcat執行穩定、可靠,而且有著開源的優勢,Tomcat已成為目前企業開
類載入順序
目錄 一、類載入做了哪些事? 之前沒有進行類載入 1.類載入,同時初始化類中靜態的屬性(賦預設值) 2.執行靜態程式碼塊 3.分配記憶體空間,同時初始化非靜態的屬性(賦預設值) 4.如果宣告屬性的同時有顯示的賦值,那麼進行顯示賦值把預設值覆蓋
類載入順序,JVM角度分析理解,類構造器方法以及例項構造器方法執行順序
今天先來分析一下經常遇到的一個問題,在筆試面試中可能會經常遇見,類中欄位程式碼塊的載入順序等,從jvm角度分析一下這個問題。我們先來看下知識點,接下來進行程式碼實踐驗證。 <clinit>,類構造器方法,在jvm第一次載入class檔案時呼叫,因為是類級別的,所
Tomcat 啟動時類載入順序
Tomcat啟動時classloader載入順序 Tomcat的class載入的優先順序一覽 1.最先是$JAVA_HOME/jre/lib/ext/下的jar檔案。 2.環境變數CLASSPATH中的jar和class檔案。 3.$CATALINA_HOME/common/cla
web.xml配置載入順序context-param 、listener、 filter、servlet
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:x
SpringMVC 專案啟動的載入順序(一)父類容器的啟動
最近在研究Spring MVC專案的啟動載入順序,做一個具體說明:一、web容器的啟動1、web專案啟動的時候,容器會優先讀取web.xml檔案,並且先找到<listener></listener>和<context-param></