Java_關於App class loader的總結

來源:互聯網
上載者:User

標籤:

Java本身是一種設計的非常簡單,非常精巧的語言,所以Java背後的原理也很簡單,歸結起來就是兩點: 

1、JVM的記憶體管理 

理解了這一點,所有和對象相關的問題統統都能解決 

2、JVM Class Loader 

理解了這一點,所有和Java相關的配置問題,包括各種App Server的配置,應用的發布問題統統都能解決 


App Class Loader 
|----- EJB Class Loader 
|----- Web App Class Loader 


如果在App Class Loader層級配置,是全域可見的。如果打包在EJB裡面,那麼就不會影響到Web Application,反之亦然,如果你在WEB-INF下面放置Hibernate,也不會影響到EJB。放在EJB Class Loader或者放在Web App Class Loader層級主要就是在局部範圍內有效,不影響到其它的應用。 

試想,如果在一個Weblogic上面配置多個虛擬域,你使用www.bruce.com網域名稱,開發你的網站,我使用www.fankai.com開發我的網站,那麼當然不希望我們的Hibernate相互幹擾,所以就可以放在 EJB Class Loader層級來配置Hibernate。 

進一步闡述一下EJB Class Loader的問題: 

先再次強調一下,Hibernate和EJB,和App Server不存在相容性問題,他們本來就是不相關的東西,就好像JDBC,相信沒有人會認為JDBC和EJB不相容吧,Hibernate也是一樣,它只和JDBC驅動,和資料庫有相容性問題,而和EJB,和App Server完全是不搭界的兩回事。凡是認為Hibernate和EJB不相容的人,其實是都是因為對EJB學習的不到家,把責任推到Hibernate身上了。 

我前面的文章提到過Class Loader的層次,這裡不重複了,總之我們先來看看Class Loader的作用範圍: 

BootStrap Class Loader: 

load JRE\lib\rt.jar, sunrsasign.jar, charsets.jar, jce.jar, jsse.jar, plugin.jar 

Ext Class Loader: 

load JRE\lib\ext目錄下的庫檔案, load JRE\classes目錄下的類 

App Class Loader: 

load CLASSPATH變數指定路徑下的類 

以上的load路徑都是寫死在JVM的C++原始碼裡面的,不能改變,詳細請見王森的《Java深度曆險》 

在一個特定的App Server上,Class Loader會繼續向下繼承,繼承的層次會根據不同的App Server有所不同,但是肯定不會變的就是: 

EJB Class Loader: 

繼承自App Class Loader,繼承層次根據App Server有所不同,一個EJB Class Loader它的load Class的範圍僅限於JAR或者EAR範圍之內。 

Web App Class Loader: 

繼承自App Class Loader,繼承層次根據App Server有所不同,一個Web App Class Loader:它的load Class的範圍在 WEB-INF\lib下的庫檔案和WEB-INF\classes目錄下的class檔案。 

Web App Class Loader很好理解,大家畢竟用的很多,App Server上的一個Web Application會建立一個Web App Class Loader的執行個體去負責load class,所以如果你想讓Hibernate只在這個Web Application內生效,把它放到WEB-INF\lib下去就好了。 

如果你把Hibernate放到了CLASSPATH變數指定的路徑下,而你在WEB-INF\lib也放了一份,那麼Web App Class Loader由於load範圍所限,它會首先找到WEB-INF\lib下的那份Hibernate,按照它的配置來初始化Hibernate。 

如果你把Hibernate放到了CLASSPATH變數指定的路徑下,但你在WEB-INF\lib什麼都沒有放,那麼Web App Class Loader由於load範圍所限,它根本什麼都找不到,於是它把load Hibernate的責任交給上一級的Class Loader,這樣直到App Class Loader,它找到了Hibernate,按照它的配置來初始化Hibernate。 

EJB Class Loader稍微複雜一點,不那麼容易理解。App Server會針對每一個EJB包檔案建立一個EJB Class Loader的執行個體,例如: 

HelloRobbin.jar 
HelloBruce.jar 

當你把這兩個jar發布到App Server上以後,會建立兩個EJB Class Loader的執行個體,分別去load這兩個EJB包,比如說: 

CLEJB_Robbin是load HelloRobbin.jar的 
CLEJB_Bruce是load HelloBruce.jar的 

那麼CLEJB_Robbin的load範圍就僅僅限於HelloRobbin.jar之內,它load不到HelloRobbin.jar之外的任何檔案,當然它也load不到HelloBruce.jar。 

說到這裡,我相信大家應該已經明白為什麼EJB規範不允許EJB有IO操作了吧?因為EJB Class Loader根本找不到jar包之外的檔案!!! 

如果現在你想實現HelloRobbin.jar和HelloBruce.jar的互相調用,那麼該怎麼辦?他們使用了不同的EJB Class Loader,相互之間是找不到對方的。解決辦法就是使用EAR。 

現在假設HelloRobbin.jar和HelloBruce.jar都使用了Hibernate,看看該怎麼打包和發布: 

HelloEJB.ear 
|------ HelloRobbin.jar 
|------ HelloBruce.jar 
|------ Hibernate2.jar 
|------ pojo.jar (定義所有的持久對象和hbm檔案的jar包) 
|------ cglib-asm.jar 
|------ commons-beanutils.jar 
|------ commons-collections.jar 
|------ commons-lang.jar 
|------ commons-logging.jar 
|------ dom4j.jar 
|------ odmg.jar 
|------ log4j.jar 
|------ jcs.jar 
|------ hibernate.properties 
|------ log4j.properties 
|------ cache.ccf 
|------ META-INF\application.xml (J2EE規範的要求,定義EAR包裡麵包括了哪幾個EJB) 

除此之外,按照EJB規範要求,HelloRobbin.jar和HelloBruce.jar還必須指出調用jar包之外的類庫的名稱,這需要在jar包的manifest檔案中定義: 

HelloRobbin.jar 
|------ META-INF\MANIFEST.MF 

MANIFEST.MF中必須包括如下一行: 

Class-Path: log4j.jar hibernate2.jar cglib-asm.jar commons-beanutils.jar commons-collections.jar commons-lang.jar 
commons-logging.jar dom4j.jar jcs.jar odmg.jar jcs.jar pojo.jar 

這樣就OK了,當把HelloEJB.ear發布到App Server上以後,App Server建立一個EJB Class Loader執行個體load EAR包裡面的EJB,再根據EJB的jar包裡面的MANIFEST.MF指出的Class-Path去尋找相應的jar包之外的類庫。 

所以一個EAR包有點類似一個Web Application,EJB Class Loader的load範圍也就是EAR範圍之內,它load不到EAR之外的檔案。除非把Hibernate定義到CLASSPATH指定的路徑下,在這種情況下,EJB Class Loader找不到Hibernate,只能交給上一級的Class Loader,最後由App Class Loader找到Hibernate,進行初始化。 

沒有寫完,繼續說... 

由於EAR這樣load Class規則,假設Robbin和Bruce都在同一個Weblogic上運行自己的網站,而我們都不希望自己的程式裡面的Hibernate配置被對方的搞亂掉,那麼我們就可以這樣來做: 

Robbin‘s Website: 

Robbin.ear 
|-------- robbin.war (把Web Application打包) 
|-------- robbin.jar (把開發的EJB打包) 
|-------- Hibernate2.jar 
.......................... 
|-------- META-INF\application.xml 


Bruce‘s Website: 

Bruce.ear 
|-------- bruce.war (把Web Application打包) 
|-------- bruce.jar (把開發的EJB打包) 
|-------- Hibernate2.jar 
.......................... 
|-------- META-INF\application.xml 

這樣在同一個App Server上運行,就可以互相不干擾。

Java_關於App class loader的總結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.