The NoteBook of EricKong

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks

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

          1、JVM的內存管理

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

          2、JVM Class Loader

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


          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域名,開發(fā)你的網(wǎng)站,我使用www.fankai.com開發(fā)我的網(wǎng)站,那么當然不希望我們的Hibernate相互干擾,所以就可以放在 EJB Class Loader級別來配置Hibernate。

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

          先再次強調一下,Hibernate和EJB,和App Server不存在兼容性問題,他們本來就是不相關的東西,就好像JDBC,相信沒有人會認為JDBC和EJB不兼容吧,Hibernate也是一樣,它只和JDBC驅動,和數(shù)據(jù)庫有兼容性問題,而和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++源代碼里面的,不能改變, 

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

          EJB Class Loader:

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

          Web App Class Loader:

          繼承自App Class Loader,繼承層次根據(jù)App Server有所不同,一個Web App Class Loader:它的load Class的范圍在 WEB-INF\lib下的庫文件和WEB-INF\classes目錄下的class文件。

          Web App Class Loader很好理解,大家畢竟用的很多,App Server上的一個Web Application會創(chuàng)建一個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包文件創(chuàng)建一個EJB Class Loader的實例,例如:

          HelloRobbin.jar
          HelloBruce.jar

          當你把這兩個jar發(fā)布到App Server上以后,會創(chuàng)建兩個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規(guī)范不允許EJB有IO操作了吧?因為EJB Class Loader根本找不到jar包之外的文件!!!

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

          現(xiàn)在假設HelloRobbin.jar和HelloBruce.jar都使用了Hibernate,看看該怎么打包和發(fā)布:

          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規(guī)范的要求,定義EAR包里面包括了哪幾個EJB)

          除此之外,按照EJB規(guī)范要求,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發(fā)布到App Server上以后,App Server創(chuàng)建一個EJB Class Loader實例load EAR包里面的EJB,再根據(jù)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,進行初始化。

          沒有寫完,繼續(xù)說...

          由于EAR這樣load Class規(guī)則,假設Robbin和Bruce都在同一個Weblogic上運行自己的網(wǎng)站,而我們都不希望自己的程序里面的Hibernate配置被對方的搞亂掉,那么我們就可以這樣來做:

          Robbin's Website:

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


          Bruce's Website:

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

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


           

          posted on 2011-12-27 15:58 Eric_jiang 閱讀(137) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 辽阳市| 松潘县| 平遥县| 营山县| 葫芦岛市| 德庆县| 秦安县| 新沂市| 洛阳市| 绥化市| 荆州市| 福海县| 营口市| 佳木斯市| 共和县| 香港| 汪清县| 开化县| 宁德市| 威远县| 奉化市| 繁峙县| 平阳县| 苗栗市| 黔江区| 安阳市| 凌海市| 会东县| 大安市| 正宁县| 东至县| 贺兰县| 上饶县| 天水市| 永修县| 丹棱县| 哈尔滨市| 临湘市| 曲松县| 天祝| 丰镇市|