專利名稱:一種類裝載處理的方法及裝置的制作方法
技術(shù)領(lǐng)域:
本發(fā)明涉及Java的類裝載處理領(lǐng)域,特別涉及一種類裝載處理的方 法及一種類裝載處理的裝置。
背景技術(shù):
目前在Intemet/Intranet/Extmnet環(huán)境中,企業(yè)級(jí)應(yīng)用系統(tǒng)大多采用三 層或多層應(yīng)用模式。為了方便開(kāi)發(fā)、部署、運(yùn)行和管理基于多層結(jié)構(gòu)的 應(yīng)用,需要以網(wǎng)絡(luò)和分布式計(jì)算的底層技術(shù)為基礎(chǔ),構(gòu)建一個(gè)完整的應(yīng) 用框架,提供相應(yīng)的支撐平臺(tái)作為多層應(yīng)用的基礎(chǔ)設(shè)施,這一支撐平臺(tái) 的關(guān)鍵就是位于中間層的應(yīng)用服務(wù)器。應(yīng)用服務(wù)器是一個(gè)創(chuàng)建、部署、 運(yùn)行、集成和維護(hù)多層分布式企業(yè)級(jí)應(yīng)用的平臺(tái)。在企業(yè)應(yīng)用中,應(yīng)用 服務(wù)器可以提供如下好處(1)提高企業(yè)應(yīng)用開(kāi)發(fā)的有效性,保障業(yè)務(wù)邏 輯和組件的重用性;(2)提高企業(yè)應(yīng)用的性能,比如,高運(yùn)行性能和響 應(yīng)時(shí)間、可伸縮性、可靠性等;(3)使企業(yè)應(yīng)用更易于監(jiān)控和管理,降 低系統(tǒng)維護(hù)和升級(jí)成本。由于應(yīng)用服務(wù)器的重要作用和關(guān)鍵地位,它已 經(jīng)成為當(dāng)今業(yè)界的一個(gè)熱點(diǎn)。類裝載是Java語(yǔ)言提供的最強(qiáng)大的機(jī)制之一。具體而言, 一個(gè)類代 表要執(zhí)行的代碼,而數(shù)據(jù)則表示其相關(guān)狀態(tài),狀態(tài)時(shí)常改變,而代碼則 不會(huì)。將一個(gè)特定的狀態(tài)與一個(gè)類相對(duì)應(yīng)起來(lái),也就意味著將一個(gè)類實(shí) 例化;盡管相同的類對(duì)應(yīng)的實(shí)例其狀態(tài)千差萬(wàn)別,但其本質(zhì)都對(duì)應(yīng)著同 一段代碼。當(dāng)Java虛擬機(jī)(Java Virtual Machine, JVM )要求類裝載器(Class Loader)裝載一個(gè)類時(shí),類裝載器首先將這個(gè)類裝載請(qǐng)求轉(zhuǎn)發(fā)給他的父裝 載器,而父裝載器會(huì)依次逐級(jí)向上傳遞請(qǐng)求,直到類裝載層次的頂部。 如果頂部的類裝載器不能完成類裝載請(qǐng)求,它的子裝載器將被調(diào)用來(lái)完 成類裝載。如果子裝載器也不能裝載類,請(qǐng)求會(huì)繼續(xù)向下傳遞,直到一 個(gè)類裝載器完成這個(gè)請(qǐng)求。例如,Web瀏覽器中的JVM需要裝載一個(gè)小應(yīng)用程序TestApplet。 JVM調(diào)用小應(yīng)用程序裝載器ACL(Applet ClassLoader, Applet類裝載器) 來(lái)完成裝載。ACL則首先請(qǐng)求它的父裝載器,即系統(tǒng)裝載器裝載 TestApplet,判斷是否裝載了這個(gè)類,由于TestApplet不在系統(tǒng)裝載器的 裝載路徑中,所以系統(tǒng)裝載器找不到這個(gè)類,也就不可能裝載成功。然 后,ACL自己裝載TestApplet。 ACL通過(guò)網(wǎng)絡(luò)找到TestApplet.class文件 并將它導(dǎo)入到了 JVM中。在裝載過(guò)程中,JVM發(fā)現(xiàn)TestApplet是從超類 java.applet.Applet繼承的。所以 JVM再次調(diào)用 ACL來(lái)裝栽 java.applet.Applet類。ACL又再次4姿上面的順序裝載Applet類,結(jié)果ACL 發(fā)現(xiàn)它的父裝載器已經(jīng)裝載了這個(gè)類,所以ACL就直接將這個(gè)已經(jīng)裝栽 的類返回給JVM,完成Applet類的裝載。接下來(lái),對(duì)Applet類的超類也 一樣處理,用以將TestApplet及所有有關(guān)的類都裝載到JVM中。
可以看出,現(xiàn)有技術(shù)需要通過(guò)網(wǎng)絡(luò)來(lái)裝載類,如果裝載的類比較多, 則對(duì)系統(tǒng)的要求比較高,并且資源耗費(fèi)比較大;即使在本地通過(guò)Applet ClassLoader的父類裝載器來(lái)裝載,每次類的裝載也需要通過(guò)非業(yè)務(wù)類裝 載器以委托上報(bào)的形式逐級(jí)裝載,裝載效率較低。
因此,本領(lǐng)域技術(shù)人員迫切需要發(fā)展出 一種可以在減少系統(tǒng)資源占 用的基礎(chǔ)上,有效提高Applet類裝載器的裝載效率的方法及裝置。
發(fā)明內(nèi)容
本發(fā)明所要解決的技術(shù)問(wèn)題是提供一種類裝載處理的方法,用以解 決現(xiàn)有技術(shù)中Applet類裝載器處理效率較低,資源占用過(guò)多的問(wèn)題。
本發(fā)明還提供了一種類裝載處理的裝置,用以保證上述方法在實(shí)際 中的實(shí)現(xiàn)及應(yīng)用。
為解決上述技術(shù)問(wèn)題,本發(fā)明實(shí)施例公開(kāi)了 一種類裝載處理的方法, 包括
生成自定義類裝載器,并在所述自定義類裝載器中添加判斷規(guī)則; 啟動(dòng)Java進(jìn)程,在所述Java進(jìn)程中創(chuàng)建所述自定義類裝載器; 設(shè)置當(dāng)前線程的上下文類裝載器為所述自定義類裝載器,由所述自 定義類裝載器按照所述判斷規(guī)則調(diào)用業(yè)務(wù)系統(tǒng)的主類。
優(yōu)選的是,所述的方法,還包括 獲取線程池中的所有線程;
設(shè)置所述線程的上下文類裝載器為所述自定義類裝載器。 優(yōu)選的是,所述判斷規(guī)則為
根據(jù)需要裝載的類的包名判斷該類是否為業(yè)務(wù)類,如果是,則直接 從所述自定義類裝載器中裝載;如果否,則從該類的父裝載器中裝載。 優(yōu)選的是,所述父裝載器為Applet類裝載器。 優(yōu)選的是,所述主類是唯一的。
本發(fā)明實(shí)施例還公開(kāi)了一種類裝載處理的裝置,包括 生成單元,用于生成自定義類裝載器,并在所述自定義類裝載器中 添加判斷MJ'J;
創(chuàng)建單元,用于啟動(dòng)Java進(jìn)程,在所述Java進(jìn)程中創(chuàng)建所述自定義 類裝載器;
設(shè)置單元,用于設(shè)置當(dāng)前線程的上下文類裝載器為所述自定義類裝 載器,由所述自定義類裝載器按照所述判斷規(guī)則調(diào)用業(yè)務(wù)系統(tǒng)的主類。 優(yōu)選的是,所述的裝置,還包括 獲取單元,用于獲取線程池中的所有線程;
分配單元,用于設(shè)置所述線程的上下文類裝載器為所述自定義類裝 載器。
優(yōu)選的是,所述判斷規(guī)則為
根據(jù)需要裝載的類的包名判斷該類是否為業(yè)務(wù)類,如果是,則直接 從所述自定義類裝載器中裝載;如果否,則從該類的父裝載器中裝載。
優(yōu)選的是,所述父裝載器為Applet類裝載器。
優(yōu)選的是,所述主類是唯一的。
與現(xiàn)有技術(shù)相比,本發(fā)明實(shí)施例具有以下優(yōu)點(diǎn)
首先,本發(fā)明通過(guò)創(chuàng)建具有判斷規(guī)則的自定義類裝載器,改變類裝 載的現(xiàn)有過(guò)程,即對(duì)于非業(yè)務(wù)類,采用現(xiàn)有過(guò)程裝載,對(duì)于業(yè)務(wù)類,無(wú) 需逐級(jí)到其父類裝載器中去加載,而可以直接在所述自定義類裝載器中 加載,從而減少了 Applet類加載器的裝載壓力,有效提高了類裝載的效
再者,由于本發(fā)明只需要在相關(guān)線程中指定該自定義類裝載器即可
實(shí)現(xiàn),因此,不會(huì)占用過(guò)多的系統(tǒng)資源,也無(wú)需增加額外的系統(tǒng)配置; 最后,本發(fā)明對(duì)于服務(wù)提供商來(lái)說(shuō),技術(shù)實(shí)現(xiàn)簡(jiǎn)單,無(wú)技術(shù)障礙, 無(wú)特殊保密算法,成本和風(fēng)險(xiǎn)較低。
圖1是一種釆用現(xiàn)有的Applet類裝載器加載非業(yè)務(wù)類的流程圖2是本發(fā)明的一種類裝載處理方法實(shí)施例的流程圖3是應(yīng)用本發(fā)明的 一種自定義類裝載器進(jìn)行類裝載的過(guò)程示意圖4是本發(fā)明的一種類裝載處理裝置實(shí)施例的結(jié)構(gòu)框圖5是應(yīng)用圖4所示的優(yōu)選實(shí)施例進(jìn)行類裝載處理的流程圖。
具體實(shí)施例方式
為使本發(fā)明的上述目的、特征和優(yōu)點(diǎn)能夠更加明顯易懂,下面結(jié)合 附圖和具體實(shí)施方式
對(duì)本發(fā)明作進(jìn)一步詳細(xì)的說(shuō)明。
參考圖1,示出了一種采用現(xiàn)有的Applet類裝載器加載非業(yè)務(wù)類(系 統(tǒng)類)的流程圖,包括以下步驟
步驟IOI、 JVM請(qǐng)求加載一個(gè)類;
步驟102、 ACL (Applet ClassLoader)調(diào)用其父類裝載器System
ClassLoader的力口載方法;
步驟103、判斷是否可以加載到類;
步驟104、如果可以加載,則加載該類,完成加載;
步驟105、如果不能加載,則調(diào)用Applet ClassLoader自己的類加載
方法;
步驟106、判斷是否可以加載到類; 步驟107、如果可以加載到類,則加載該類,完成加載; 步驟108、如果不能加載到類,則拋出錯(cuò)誤信息(例如,類加載異常), 結(jié)束加載。
其中,Applet ClassLoader (小應(yīng)用程序裝載器)為系統(tǒng)裝載器,它 可以從用戶指定的網(wǎng)絡(luò)上的特定目錄裝載小應(yīng)用程序(Applet)代碼。
Applet可以直接嵌入到網(wǎng)頁(yè)或者其他特定的容器中,并能夠產(chǎn)生特殊的 效果。但是,Applet必須運(yùn)行于某個(gè)特定的"容器,這個(gè)容器可以是瀏覽 器本身,也可以是通過(guò)各種插件,或者包括支持Applet的移動(dòng)設(shè)備在內(nèi) 的其他各種程序來(lái)運(yùn)行。與一般的Java應(yīng)用程序不同,Applet不是通過(guò) main方法來(lái)運(yùn)行的,而是必須創(chuàng)建一個(gè)HTML文件,通過(guò)編寫HTML語(yǔ) 言代碼告訴瀏覽器載入何種Applet以及如何運(yùn)行。在運(yùn)行時(shí),Applet通 常會(huì)與用戶進(jìn)行互動(dòng),顯示動(dòng)態(tài)的畫面,并且還會(huì)遵循嚴(yán)格的安全檢查, 阻止?jié)撛诘牟话踩蛩兀?,根?jù)安全策略限制Applet對(duì)客戶端文件 系統(tǒng)的訪問(wèn)。可以看出,采用這種現(xiàn)有的加載方法,對(duì)于非業(yè)務(wù)類的裝載可以在 步驟105或108中完成,然而,如果是業(yè)務(wù)類的裝載,則需要到步驟lll 才能完成。本發(fā)明實(shí)施例的核心構(gòu)思之一在于,通過(guò)自定義類裝載器對(duì)需要加 載的類進(jìn)行判斷,如果該類為業(yè)務(wù)類,則直接從該自定義類裝載器中裝 載;如果該類不是業(yè)務(wù)類,則按照現(xiàn)有方法從該類的父裝載器中裝載, 即通過(guò)改變現(xiàn)有的類裝載邏輯,簡(jiǎn)單、有效地提高類裝載的效率。參照?qǐng)D2,示出了本發(fā)明的一種類裝載處理的方法實(shí)施例的流程圖, 具體包括以下步驟步驟201、生成自定義類裝載器,并在所述自定義類裝載器中添加判 斷頭見(jiàn)則;步驟202、啟動(dòng)Java進(jìn)程,在所述Java進(jìn)程中創(chuàng)建所述自定義類裝 載器;步驟203、設(shè)置當(dāng)前線程的上下文類裝載器為所述自定義類裝載器, 由所述自定義類裝載器按照所述判斷規(guī)則調(diào)用業(yè)務(wù)系統(tǒng)的主類。需要注意的是,所述自定義類裝載器需要繼承java.lang.ClassLoader或者 它的子類。在實(shí)例化每個(gè)類裝載器對(duì)象時(shí),需要指定一個(gè)父對(duì)象,在本 實(shí)施例中,所述父對(duì)象優(yōu)選為Applet類裝載器。遵循本發(fā)明的上述核心構(gòu)思之一,為了改變業(yè)務(wù)類的裝載邏輯,在 本實(shí)施例中,所述判斷規(guī)則可以為根據(jù)需要裝載的類的包名判斷該類
是否為業(yè)務(wù)類,如果是,則直接從所述自定義類裝載器中裝載;如果否, 則從該類的父裝載器中裝載。在這種情況下, 一種生成具有這種判斷規(guī)則的自定義類裝載器的方法為一、 編寫自定義類裝載器Custom ClassLoader;二、 根據(jù)需要裝載的類的包名在Custom ClassLoader中添加判斷規(guī)則;例如,以如下代碼實(shí)現(xiàn)protected boolean isSystemClass(String className) 在實(shí)際中,業(yè)務(wù)類的包名通常以com.為起始字符,其后連接業(yè)務(wù)系 統(tǒng)及其子系統(tǒng)的簡(jiǎn)稱,例如, 一種客戶關(guān)系管理系統(tǒng)中的客戶基礎(chǔ)資料 管理類的包名為com.crm.basemanager; 而非業(yè)務(wù)類的包名通常以netscape.、 com.sun.、 java.、 javax.、.....等為起4臺(tái)字符,也章尤是i兌,通過(guò)分析不同的包名命名規(guī)則,即可判定所述類是否為業(yè)務(wù)類,應(yīng)用本發(fā)明 實(shí)施例時(shí),本領(lǐng)域技術(shù)人員可以根據(jù)具體的業(yè)務(wù)系統(tǒng)獲取到包名的命名 規(guī)則,從而具體設(shè)定相應(yīng)的判斷規(guī)則,本發(fā)明對(duì)此不需要進(jìn)行限定。 例如, 一種設(shè)置判斷規(guī)則的實(shí)現(xiàn)代碼為 protected boolean isSystemClass(String className) { if(className.indexOf("netscape.")>=0 〃包名以netscape.為起始字符 的類為非業(yè)務(wù)類HclassName.indexOf("com.sun.")>=0 〃包名以com.sun.為起始字符的 類為非業(yè)務(wù)類||className.indexOf("sun.")>=0 〃包名以sun.為起始字符的類為非業(yè)務(wù)類||className.indexOf("java.")>=0 〃包名以java.為起始字符的類為非業(yè)務(wù)類||className.indexOf("javax.")>=0){ 〃包名以javax.為起始字符的類為 非業(yè)務(wù)類return true;}else{ 〃否則為業(yè)務(wù)類 return false;
三、 添加業(yè)務(wù)類的讀取M^'J; 例如,通過(guò)以下代碼實(shí)5見(jiàn)protected Object loadOperationClass(String className , String r6sNam6)應(yīng)用本步驟可以實(shí)現(xiàn)以遠(yuǎn)程方式下載Jar包,并讀取資源或類文件。四、 重載父類的getResource ()方法;本方法調(diào)用前一步驟三的規(guī)則,直接從Custom ClassLoader中加載業(yè) 務(wù)類,即從業(yè)務(wù)包中讀取資源文件,完成資源文件的加載。五、 重載父類的loadClass ()方法。本方法調(diào)用上述步驟二的規(guī)則,判斷需要加載的類是業(yè)務(wù)類還是非業(yè)務(wù)類,如果是非業(yè)務(wù)類則到指定的父裝載器Applet裝載器中加載,如果是業(yè)務(wù)類則直接調(diào)用步驟三的規(guī)則進(jìn)行業(yè)務(wù)類讀取,進(jìn)而完成業(yè)務(wù)類的加載。例如,其實(shí)現(xiàn)代碼為 /*承*力口載類*如果是非業(yè)務(wù)類(包括本加載器本身需要加載的類)則到父類加 載器中加載;如果是業(yè)務(wù)類則直接從本加載器中直接加載public Class loadClass(String className , boolean resolve) throws ClassNotFoundException {〃該類是否已經(jīng)加載過(guò)c = findLoadedClass(className);if(c == null) {if(c ==mill) { try {
〃判斷是否是非業(yè)務(wù)類if(isSystemClass(className)) {〃是非業(yè)務(wù)類,從父加載器中加載 c = getParentO.loadClass(className); }else{〃是業(yè)務(wù)類,從本加載器中加載c = (Class) loadOperationClass(className, clsName); } catch (ClassNotFoundException cnfex) {} }啟動(dòng)Java進(jìn)程運(yùn)行Java程序時(shí),首先需要運(yùn)4亍Java虛擬機(jī)(JVM ), 再將包含在類(.class)文件中的字節(jié)碼裝載到JVM中,這種裝載是由類 裝載器(ClassLoader )和它的子類來(lái)實(shí)現(xiàn)的。類裝載器并不是原封不動(dòng) 地將類文件的字節(jié)碼裝載到JVM,而是將類文件中的內(nèi)容轉(zhuǎn)換成JVM使 用的類字節(jié)碼。通過(guò)類裝載器裝載到JVM中的字節(jié)碼數(shù)據(jù),就成了可執(zhí) 行的代碼。JVM規(guī)范定義了兩種類型的類裝載器啟動(dòng)內(nèi)裝載器(bootstrap) 和用戶自定義裝載器(user-defined class loader)。具體而言,JVM本身包含 了一個(gè)類裝載器稱為Bootstrap ClassLoader,和JVM —樣,Bootstrap ClassLoader是用本地代碼實(shí)現(xiàn)的,它負(fù)責(zé)裝載核心Java Class,即所有 java,開(kāi)頭的類。另夕卜,JVM還會(huì)提供兩個(gè)類裝載器Extension ClassLoader 和System ClassLoader, 它們都是用 Java i吾言編寫的,由Bootstrap ClassLoader裝載。其中Extension ClassLoader負(fù)責(zé)裝載擴(kuò)展的Java class, 例如所有javax.*開(kāi)頭的類和存放在JRE的ext目錄下的類,System ClassLoader是一個(gè)特殊的用戶自定義類裝載器,由JVM的實(shí)現(xiàn)者4是供, 在編程者不特別指定裝載器的情況下默認(rèn)裝載用戶類,它可以從 java.class.path(CLASSPATH,環(huán)境變量)中裝載代碼,同時(shí)還可以作為用 戶自定義類裝載器的缺省父裝載器。Java的類裝載模型是一種代理 (delegation)模型。當(dāng)JVM要求類裝載器裝載一個(gè)類時(shí),類裝載器首先將 這個(gè)類裝載請(qǐng)求轉(zhuǎn)發(fā)給他的父裝載器。只有當(dāng)父裝載器沒(méi)有裝載并無(wú)法 裝載這個(gè)類時(shí),類裝載器才獲得裝載這個(gè)類的機(jī)會(huì)。這樣,所有類裝載 器的代理關(guān)系構(gòu)成了 一種樹(shù)狀的關(guān)系。樹(shù)的根是類的Bootstrap ClassLoader ,在JVM中它以"null"表示。除Bootstrap ClassLoader以外的 類裝載器有且僅有一個(gè)父裝載器。在本實(shí)施例中,調(diào)用所述自定義類裝載器,首先需要在Java進(jìn)程中 創(chuàng)建所述自定義類裝載器,其具體創(chuàng)建方法可以采用Java語(yǔ)言的new關(guān) 4走字進(jìn)行創(chuàng)建。例如, 一種創(chuàng)建ClassLoader對(duì)象的代碼為ClassLoader myClassLoader = new myClassLoader();在實(shí)際中,類(.class文件)可以存在目錄或Jar包中,或者存儲(chǔ)在 兩者的組合中,但是只有在它們位于類路徑中的某個(gè)地方時(shí),javac編譯 器或解釋器才可以找到它們??梢钥闯?,類路徑可以用于使Java解釋器 和javac編譯器知道去何處查找它們要執(zhí)行或?qū)氲念?。因而,在?chuàng)建所 述自定義類裝載器時(shí),還可以在所述自定義類裝載器對(duì)象中設(shè)置添加路 徑的行為,在這種情況下,則可以通過(guò)調(diào)用所述添加路徑的行為,將類 路徑添加至所述自定義類裝載器對(duì)象中。添加路徑的行為會(huì)將所加入的 資源路徑逐個(gè)掃描,直至找到所需的類資源為止。當(dāng)然,本領(lǐng)域技術(shù)人員根據(jù)需要或經(jīng)驗(yàn)采用其它方法創(chuàng)建自定義類 裝載器也是可行的,本發(fā)明對(duì)此不需要進(jìn)行限定。運(yùn)行JVM實(shí)例時(shí),即可啟動(dòng)相應(yīng)的線程。7>知的是,線程與進(jìn)程相 似,是一段完成某個(gè)特定功能的代碼,是程序中單個(gè)順序的流控制;但 與進(jìn)程不同的是,同類的多個(gè)線程是共享 一 塊內(nèi)存空間和 一 組系統(tǒng)資源, 而線程本身的數(shù)據(jù)通常只有微處理器的寄存器數(shù)據(jù),以及一個(gè)供程序執(zhí) 行時(shí)使用的堆棧。所以系統(tǒng)在產(chǎn)生一個(gè)線程,或者在各個(gè)線程之間切換 時(shí),負(fù)擔(dān)要比進(jìn)程小的多,正因如此,線程被稱為輕負(fù)荷進(jìn)程(light-weight
process )。 一個(gè)進(jìn)程中可以包含多個(gè)線程。在Java中,線程由三部分組成 (1 )虛擬的cpu,封裝在java.lang.Thread類中;(2 ) CPU所執(zhí)行的代碼, 傳遞給Thread類;(3 ) CPU所處理的數(shù)據(jù),傳遞給Thread類。公知的是,Java語(yǔ)言本身為線程提供了設(shè)置線程的上下文類裝載器 的方法,線程上下文類加載器是在Java2(J2SE)時(shí)引入的。每個(gè)線程都有 一個(gè)關(guān)聯(lián)的上下文類加載器。如果使用newThread()方式生成新的線程, 新線程將繼承其父線程的上下文類加載器。如果程序?qū)€程上下文類加 載器沒(méi)有任何改動(dòng)的話,程序中所有的線程將都使用系統(tǒng)類加載器作為 上下文類加載器。在本實(shí)施例中,使用創(chuàng)建的線程對(duì)象,讓其執(zhí)行"設(shè)置類裝載器"這個(gè) 行為,并將之前設(shè)置的自定義類裝載器對(duì)象導(dǎo)入,則這個(gè)線程對(duì)象的類 裝載器已經(jīng)被設(shè)置為自定義類裝載器。在本實(shí)例中,通過(guò)在當(dāng)前線程上 下文中指定其類裝載器為所述自定義類裝載器,則當(dāng)前線程后續(xù)調(diào)用的 類或創(chuàng)建的類裝載器都會(huì)基于所述自定義類裝載器來(lái)加載。在這種情況下,類裝載行為由所述自定義類裝載器來(lái)執(zhí)行,裝載不 同類的邏輯也是由所述自定義的類裝載器控制,具體而言,即利用Java 反射機(jī)制,由所述自定義類裝載器來(lái)加載業(yè)務(wù)系統(tǒng)的主類,例如,應(yīng)用 程序中含有main方法并且訪問(wèn)控制符為public的類,或,小應(yīng)用程序 java.applet.Applet類的子類,即,有init(), start(), destory(), paint()的類、 extends Applet或JApplet等。在本實(shí)施例中,所述主類是唯一 的。參考圖3,示出了應(yīng)用本發(fā)明的一種自定義類裝載器(Custom ClassLoader)進(jìn)行類裝載的過(guò)程示意圖,包括以下步驟步驟301、 JVM請(qǐng)求加載一個(gè)類;步驟302、 Custom ClassLoader判斷該類是否為業(yè)務(wù)類,如果是業(yè)務(wù) 類,則執(zhí)行步驟303;如果是非業(yè)務(wù)類,則執(zhí)行以下步驟304; 步驟303、直接調(diào)用Custom ClassLoader進(jìn)行加載; 步驟304、 Custom ClassLoader調(diào)用其父類裝載器Applet ClassLoader 尋找要裝載的類;步驟305 、 Applet ClassLoader調(diào)用其父類裝載器System ClassLoader 尋找要裝載的類; 步驟306、判斷是否在System ClassLoader中找到要裝載的類,如果 是,則執(zhí)行步驟309,裝載該類;如果否,則執(zhí)行下一步驟;步驟307、判斷是否在Applet ClassLoader中找到要裝載的類,如果 是,則執(zhí)行步驟309,裝載該類;如果否,則執(zhí)行步驟308;步驟308、拋出異常給用戶;步驟309、裝載該類。在Java中,如果每當(dāng)一個(gè)請(qǐng)求到達(dá)就創(chuàng)建一個(gè)新線程,開(kāi)銷是相當(dāng) 大的。在實(shí)際使用中,每個(gè)請(qǐng)求創(chuàng)建新線程的服務(wù)器在創(chuàng)建和銷毀線程 上花費(fèi)的時(shí)間和消耗的系統(tǒng)資源,甚至可能要比花在處理實(shí)際的用戶請(qǐng) 求的時(shí)間和資源要多得多。除了創(chuàng)建和銷毀線程的開(kāi)銷之外,活動(dòng)的線 程也需要消耗系統(tǒng)資源。如果在一個(gè)JVM里創(chuàng)建太多的線程,可能會(huì)導(dǎo) 致系統(tǒng)由于過(guò)度消耗內(nèi)存或"切換過(guò)度"而導(dǎo)致系統(tǒng)資源不足。為了防止資 源不足,服務(wù)器應(yīng)用程序需要一些辦法來(lái)限制任何給定時(shí)刻處理的請(qǐng)求 數(shù)目,盡可能減少創(chuàng)建和銷毀線程的次數(shù),特別是一些資源耗費(fèi)比較大 的線程的創(chuàng)建和銷毀,盡量利用已有對(duì)象來(lái)進(jìn)行服務(wù),即可以采用線程 池來(lái)解決上述問(wèn)題。線程池主要用來(lái)解決線程生命周期開(kāi)銷問(wèn)題和資源不足問(wèn)題。通過(guò) 對(duì)多個(gè)任務(wù)重用線程,線程創(chuàng)建的開(kāi)銷就被分?jǐn)偟搅硕鄠€(gè)任務(wù)上了,而 且由于在請(qǐng)求到達(dá)時(shí)線程已經(jīng)存在,所以消除了線程創(chuàng)建所帶來(lái)的延遲。這樣,就可以立即為請(qǐng)求服務(wù),使應(yīng)用程序響應(yīng)更快。另外,通過(guò)適當(dāng) 地調(diào)整線程池中的線程數(shù)目可以防止出現(xiàn)資源不足的情況。一個(gè)線程池至少包含線程池管理器、工作線程、任務(wù)隊(duì)列、任務(wù)接 口等部分。其中線程池管理器(ThreadPool Manager)的作用是創(chuàng)建、銷 毀并管理線程池,將工作線程放入線程池中;工作線程是一個(gè)可以循環(huán) 執(zhí)行任務(wù)的線程,在沒(méi)有任務(wù)時(shí)進(jìn)行等待;任務(wù)隊(duì)列的作用是提供一種 緩沖機(jī)制,將沒(méi)有處理的任務(wù)放在任務(wù)隊(duì)列中;任務(wù)接口是每個(gè)任務(wù)必 須實(shí)現(xiàn)的接口,主要用來(lái)規(guī)定任務(wù)的入口、任務(wù)執(zhí)行完后的收尾工作、 任務(wù)的執(zhí)行狀態(tài)等,工作線程通過(guò)該接口調(diào)度任務(wù)的執(zhí)行。例如,線程 池的創(chuàng)建以及從線程池中取出線程的操作代碼如下所示public class ThreadPool private Stack threadpool = new Stack(); private int poolSize; private int currSize=0; public void setSize(int n){poolSize = n;public void runOfor(int i=0; i<poolSize; i++)WorkThread workthread=new WorkThread(); threadpool.push(workthread); currSize++;public synchronized WorkThread getworker()if (threadpool.empty(》system.out.println("stack is empty"); elsetry{ return threadpool.pop();} catch (EmptyStackException e)"在本實(shí)施例中,采用自定義裝載器加栽主類后,相關(guān)的線程池也可能形 成,在這種情況下,本發(fā)明還可以包括以下步驟 獲取線程池中的所有線程;設(shè)置所述線程的上下文類裝載器為所述自定義類裝載器。
例3。,示例代^馬i口下 public void initContextCL()SwingUtilities.invokeLater(new Runnable() { public void runO {Thread thread = Thread.currentThread(); 〃獲耳又當(dāng)前纟戔禾呈 ThreadGroup tg = thread.getThreadGroup();〃獲耳又線程池 if(tg != null) {for(;;) {〃獲取頂級(jí)線程池ThreadGroup parent = tg.getParent(); if(parent == null) {break; } else {tg = parent;Thread[] threads = new Thread[tg.activeCount()]; int count = tg.enumerate(threads); for(inti=0;i<count;i++)if(threads[i].getContextClassLoader()== MyApplet.class.getClassLoader()) 〃將上下文ClassLoader設(shè)置為加載業(yè)務(wù)主類的ClassLoader, 〃即CustomClassLoaderthreads[i].setContextClassLoader(MyMain.class.getClassLoader());}); 通過(guò)上述步驟,可以將線程池中的所有線程的上下文類都設(shè)置為自 定義類裝載器,以確保所有線程后續(xù)調(diào)用的類或創(chuàng)建的類裝載器都能通 過(guò)該自定義類裝載器來(lái)加載。綜上,本發(fā)明通過(guò)創(chuàng)建具有判斷規(guī)則的自定義類裝載器,改變類裝 載的現(xiàn)有過(guò)程,即對(duì)于非業(yè)務(wù)類,采用現(xiàn)有過(guò)程裝載,對(duì)于業(yè)務(wù)類,無(wú) 需逐級(jí)到其父類裝載器中去加載,而可以直接在所述自定義類裝載器中加載,從而減少了 Applet類加載器的裝載壓力,有效提高了類裝載的效 率;并且,由于本發(fā)明只需要在相關(guān)線程中指定該自定義類裝載器即可 實(shí)現(xiàn),因此,不會(huì)占用過(guò)多的系統(tǒng)資源,也無(wú)需增加額外的系統(tǒng)配置。參考圖4,示出了本發(fā)明的一種類裝載處理裝置實(shí)施例的結(jié)構(gòu)框圖, 包括以下單元生成單元401,用于生成自定義類裝載器,并在所述自定義類裝載器 中添加判斷MJ'J;創(chuàng)建單元402,用于啟動(dòng)Java進(jìn)程,在所述Java進(jìn)程中創(chuàng)建所述自 定義類裝載器;設(shè)置單元403,用于設(shè)置當(dāng)前線程的上下文類裝載器為所述自定義類 裝載器,由所述自定義類裝載器按照所述判斷規(guī)則調(diào)用業(yè)務(wù)系統(tǒng)的主類。 優(yōu)選的是,在本實(shí)施例中,所述的裝置還可以包括以下單元 獲取單元404,用于獲取線程池中的所有線程; 分配單元405,用于設(shè)置所述線程的上下文類裝載器為所述自定義類為針對(duì)不同的類采用不同的裝載邏輯,優(yōu)選的是,在本實(shí)施例中,所述判斷規(guī)則可以為根據(jù)需要裝載的類的包名判斷該類是否為業(yè)務(wù)類,如果是,則直接 從所述自定義類裝載器中裝載;如果否,則從該類的父裝載器中裝載。在實(shí)際中,所述父裝載器為Applet類裝載器,并且,所述主類是唯 一的。參考圖5,示出了應(yīng)用圖4所示的優(yōu)選實(shí)施例進(jìn)行類裝載處理的流程 圖,具體包括以下步驟步驟501、生成單元生成自定義類裝載器,并在所述自定義類裝載器
中添加判斷MJ'J;步驟502、創(chuàng)建單元啟動(dòng)Java進(jìn)程,在所述Java進(jìn)程中創(chuàng)建所述自 定義類裝載器;步驟503、設(shè)置單元設(shè)置當(dāng)前線程的上下文類裝載器為所述自定義類 裝載器,由所述自定義類裝載器按照所述判斷規(guī)則調(diào)用業(yè)務(wù)系統(tǒng)的主類; 步驟504、獲取單元獲取線程池中的所有線程;步驟505、分配單元設(shè)置所述線程的上下文類裝載器為所述自定義類 裝載器。對(duì)于裝置實(shí)施例而言,由于其基本相應(yīng)于方法實(shí)施例,所以描述的 比較簡(jiǎn)單,相關(guān)之處參見(jiàn)方法實(shí)施例的部分說(shuō)明即可。本發(fā)明可以用于眾多通用或?qū)S玫挠?jì)算系統(tǒng)環(huán)境或配置中。例如 個(gè)人計(jì)算機(jī)、服務(wù)器計(jì)算機(jī)、手持設(shè)備或便攜式設(shè)備、平板型設(shè)備、多 處理器系統(tǒng)、基于微處理器的系統(tǒng)、置頂盒、可編程的消費(fèi)電子設(shè)備、 網(wǎng)絡(luò)PC、小型計(jì)算機(jī)、大型計(jì)算機(jī)、包括以上任何系統(tǒng)或設(shè)備的分布式 計(jì)算環(huán)境等等。此外,本發(fā)明還可以在由計(jì)算機(jī)執(zhí)行的計(jì)算機(jī)可執(zhí)行指 令的一般上下文中描述,例如程序模塊。 一般地,程序模塊包括執(zhí)行特 定任務(wù)或?qū)崿F(xiàn)特定抽象數(shù)據(jù)類型的例程、程序、對(duì)象、組件、數(shù)據(jù)結(jié)構(gòu) 等等。也可以在分布式計(jì)算環(huán)境中實(shí)踐本發(fā)明,在這些分布式計(jì)算環(huán)境 中,由通過(guò)通信網(wǎng)絡(luò)而被連接的遠(yuǎn)程處理設(shè)備來(lái)執(zhí)行任務(wù)。在分布式計(jì) 算環(huán)境中,程序模塊可以位于包括存儲(chǔ)設(shè)備在內(nèi)的本地和遠(yuǎn)程計(jì)算機(jī)存 儲(chǔ)介質(zhì)中。以上對(duì)本發(fā)明所提供的一種類裝載處理的方法及一種類裝載處理的式進(jìn)行了闡述,以上實(shí)施例的說(shuō)明只是用于幫助理解本發(fā)明的方法及其 核心思想;同時(shí),對(duì)于本領(lǐng)域的一般技術(shù)人員,依據(jù)本發(fā)明的思想,在具體實(shí)施方式
及應(yīng)用范圍上均會(huì)有改變之處,綜上所述,本說(shuō)明書內(nèi)容 不應(yīng)理解為對(duì)本發(fā)明的限制。
權(quán)利要求
1、一種類裝載處理的方法,其特征在于,所述方法包括生成自定義類裝載器,并在所述自定義類裝載器中添加判斷規(guī)則;啟動(dòng)Java進(jìn)程,在所述Java進(jìn)程中創(chuàng)建所述自定義類裝載器;設(shè)置當(dāng)前線程的上下文類裝載器為所述自定義類裝載器,由所述自定義類裝載器按照所述判斷規(guī)則調(diào)用業(yè)務(wù)系統(tǒng)的主類。
2、 如權(quán)利要求l所述的方法,其特征在于,還包括 獲取線程池中的所有線程;設(shè)置所述線程的上下文類裝載器為所述自定義類裝載器。
3、 如權(quán)利要求1或2所述的方法,其特征在于,所述判斷規(guī)則為 根據(jù)需要裝載的類的包名判斷該類是否為業(yè)務(wù)類,如果是,則直接從所述自定義類裝載器中裝載;如果否,則從該類的父裝載器中裝載。
4、 如權(quán)利要求3所述的方法,其特征在于,所述父裝載器為Applet 類裝載器。
5、 如權(quán)利要求3或4所述的方法,其特征在于,所述主類是唯一的。
6、 一種類裝載處理的裝置,其特征在于,包括生成單元,用于生成自定義類裝載器,并在所述自定義類裝載器中 添加判斷^L則;創(chuàng)建單元,用于啟動(dòng)Java進(jìn)程,在所述Java進(jìn)程中創(chuàng)建所述自定義 類裝載器;設(shè)置單元,用于設(shè)置當(dāng)前線程的上下文類裝載器為所述自定義類裝 載器,由所述自定義類裝載器按照所述判斷規(guī)則調(diào)用業(yè)務(wù)系統(tǒng)的主類。
7、 如權(quán)利要求6所述的裝置,其特征在于,還包括 獲取單元,用于獲取線程池中的所有線程;分配單元,用于設(shè)置所述線程的上下文類裝載器為所述自定義類裝 載器。
8、 如權(quán)利要求6或7所述的裝置,其特征在于,所述判斷規(guī)則為 根據(jù)需要裝載的類的包名判斷該類是否為業(yè)務(wù)類,如果是,則直接從所述自定義類裝載器中裝載;如果否,則從該類的父裝載器中裝載。
9、 如權(quán)利要求8所述的裝置,其特征在于,所述父裝載器為Applet 類裝載器。
10、 如權(quán)利要求8或9所述的方法,其特征在于,所述主類是唯一的。
全文摘要
本發(fā)明公開(kāi)了一種類裝載處理的方法,包括生成自定義類裝載器,并在所述自定義類裝載器中添加判斷規(guī)則;啟動(dòng)Java進(jìn)程,在所述Java進(jìn)程中創(chuàng)建所述自定義類裝載器;設(shè)置當(dāng)前線程的上下文類裝載器為所述自定義類裝載器,由所述自定義類裝載器按照所述判斷規(guī)則調(diào)用業(yè)務(wù)系統(tǒng)的主類。本發(fā)明通過(guò)改變類裝載的現(xiàn)有過(guò)程,即對(duì)于非業(yè)務(wù)類,采用現(xiàn)有過(guò)程裝載,對(duì)于業(yè)務(wù)類,無(wú)需逐級(jí)到其父類裝載器中去加載,而可以直接在所述自定義類裝載器中加載,從而減少了Applet類加載器的裝載壓力,有效提高了類裝載的效率;并且,由于本發(fā)明只需要在相關(guān)線程中指定該自定義類裝載器即可實(shí)現(xiàn),因此,不會(huì)占用過(guò)多的系統(tǒng)資源,也無(wú)需增加額外的系統(tǒng)配置。
文檔編號(hào)G06F9/46GK101118497SQ200710152260
公開(kāi)日2008年2月6日 申請(qǐng)日期2007年9月20日 優(yōu)先權(quán)日2007年9月20日
發(fā)明者唐國(guó)偉 申請(qǐng)人:金蝶軟件(中國(guó))有限公司