<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 30,  comments - 50,  trackbacks - 0
      2007年12月7日
        1.先安裝一個(gè)Subclipse,地址:http://subclipse.tigris.org/ 
        2.可以通過(guò)Eclipse的Update Site安裝方式:http://subclipse.tigris.org/update_1.4.x或者下載下來(lái)之后,解壓縮復(fù)制到Eclipse目錄即可。
        3.啟動(dòng)程序后在Eclipse配置項(xiàng)的Team里面就會(huì)多出SVN,就可以進(jìn)行配置了。
        4.想要提交一個(gè)項(xiàng)目,對(duì)項(xiàng)目點(diǎn)擊右鍵Team——Share project就可以將項(xiàng)目導(dǎo)入SVN了。
        需要注意的是,請(qǐng)不要將動(dòng)態(tài)生成的目錄添加到SVN,否則其他人Check out的之后,再Update容易出錯(cuò),例如classes目錄,不需要提交上去,本地就可以了。
        想要對(duì)比本地和服務(wù)器上的源代碼,請(qǐng)使用Team——Synchronize with Repository,列出不同的文件之后,雙擊,既可以對(duì)比兩個(gè)文件。
        WebService項(xiàng)目會(huì)生成一個(gè)。apt_generated目錄,里面包含了一些源代碼,提交的時(shí)候不需要提交上去,MyEclipse在獲得SVN的項(xiàng)目之后,會(huì)自動(dòng)生成這個(gè)目錄和底下的文件。
    posted @ 2008-12-19 11:16 心。 閱讀(307) | 評(píng)論 (0)編輯 收藏
    1) Assigned
          主鍵由外部程序負(fù)責(zé)生成,無(wú)需Hibernate參與。
    2) hilo
          通過(guò)hi/lo 算法實(shí)現(xiàn)的主鍵生成機(jī)制,需要額外的數(shù)據(jù)庫(kù)表保存主鍵生成歷史狀態(tài)。
    3) seqhilo
          與hilo 類似,通過(guò)hi/lo 算法實(shí)現(xiàn)的主鍵生成機(jī)制,只是主鍵歷史狀態(tài)保存在Sequence中,適用于支持Sequence的數(shù)據(jù)庫(kù),如Oracle。
    4) increment
          主鍵按數(shù)值順序遞增。此方式的實(shí)現(xiàn)機(jī)制為在當(dāng)前應(yīng)用實(shí)例中維持一個(gè)變量,以保存著當(dāng)前的最大值,之后每次需要生成主鍵的時(shí)候?qū)⒋酥导?作為主鍵。
          這種方式可能產(chǎn)生的問(wèn)題是:如果當(dāng)前有多個(gè)實(shí)例訪問(wèn)同一個(gè)數(shù)據(jù)庫(kù),那么由于各個(gè)實(shí)例各自維護(hù)主鍵狀態(tài),不同實(shí)例可能生成同樣的主鍵,從而造成主鍵重復(fù)異常。因此,如果同一數(shù)據(jù)庫(kù)有多個(gè)實(shí)例訪問(wèn),此方式必須避免使用。
    5) identity
           采用數(shù)據(jù)庫(kù)提供的主鍵生成機(jī)制。如DB2、SQL Server、MySQL中的主鍵生成機(jī)制。
    6) sequence
           采用數(shù)據(jù)庫(kù)提供的sequence 機(jī)制生成主鍵。如Oralce 中的Sequence。
    7) native
           由Hibernate根據(jù)底層數(shù)據(jù)庫(kù)自行判斷采用identity、hilo、sequence其中一種作為主鍵生成方式。
    8) uuid.hex
           由Hibernate基于128 位唯一值產(chǎn)生算法生成16 進(jìn)制數(shù)值(編碼后以長(zhǎng)度32 的字符串表示)作為主鍵。
    9) uuid.string
           與uuid.hex 類似,只是生成的主鍵未進(jìn)行編碼(長(zhǎng)度16)。在某些數(shù)據(jù)庫(kù)中可能出現(xiàn)問(wèn)題(如PostgreSQL)。
    10) foreign
           使用外部表的字段作為主鍵。
    posted @ 2008-08-22 15:36 心。 閱讀(299) | 評(píng)論 (0)編輯 收藏

      JAR 文件是什么?
      JAR 文件格式以流行的 ZIP 文件格式為基礎(chǔ),用于將許多個(gè)文件聚集為一個(gè)文件。與 ZIP 文件不同的是,JAR 文件不僅用于壓縮和發(fā)布,而且還用于部署和封裝庫(kù)、組件和插件程序,并可被像編譯器和 JVM 這樣的工具直接使用。在 JAR 中包含特殊的文件,如 manifests 和部署描述符,用來(lái)指示工具如何處理特定的 JAR。

      一個(gè) JAR 文件可以用于:
      □ 用于發(fā)布和使用類庫(kù)
      □ 作為應(yīng)用程序和擴(kuò)展的構(gòu)建單元
      □ 作為組件、applet 或者插件程序的部署單位
      □ 用于打包與組件相關(guān)聯(lián)的輔助資源

      JAR 文件格式提供了許多優(yōu)勢(shì)和功能,其中很多是傳統(tǒng)的壓縮格式如 ZIP 或者 TAR 所沒(méi)有提供的。它們包括:

      ☆ 安全性。 可以對(duì) JAR 文件內(nèi)容加上數(shù)字化簽名。這樣,能夠識(shí)別簽名的工具就可以有選擇地為您授予軟件安全特權(quán),這是其他文件做不到的,它還可以檢測(cè)代碼是否被篡改過(guò)。

      ☆ 減少下載時(shí)間。 如果一個(gè) applet 捆綁到一個(gè) JAR 文件中,那么瀏覽器就可以在一個(gè) HTTP 事務(wù)中下載這個(gè) applet 的類文件和相關(guān)的資源,而不是對(duì)每一個(gè)文件打開(kāi)一個(gè)新連接。

      ☆ 壓縮。JAR 格式允許您壓縮文件以提高存儲(chǔ)效率。

      ☆ 傳輸平臺(tái)擴(kuò)展。 Java 擴(kuò)展框架(Java Extensions Framework)提供了向 Java 核心平臺(tái)添加功能的方法,這些擴(kuò)展是用 JAR 文件打包的(Java 3D 和 JavaMail 就是由 Sun 開(kāi)發(fā)的擴(kuò)展例子)。

      ☆ 包密封。 存儲(chǔ)在 JAR 文件中的包可以選擇進(jìn)行密封,以增強(qiáng)版本一致性和安全性。密封一個(gè)包意味著包中的所有類都必須在同一 JAR 文件中找到。

      ☆ 包版本控制。 一個(gè) JAR 文件可以包含有關(guān)它所包含的文件的數(shù)據(jù),如廠商和版本信息。

      ☆ 可移植性。 處理 JAR 文件的機(jī)制是 Java 平臺(tái)核心 API 的標(biāo)準(zhǔn)部分。

      壓縮的和未壓縮的 JAR
      jar 工具在默認(rèn)情況下壓縮文件。未壓縮的 JAR 文件一般可以比壓縮過(guò)的 JAR 文件更快地裝載,因?yàn)樵谘b載過(guò)程中要解壓縮文件,但是未壓縮的文件在網(wǎng)絡(luò)上的下載時(shí)間可能更長(zhǎng)。

      META-INF 目錄
      大多數(shù) JAR 文件包含一個(gè) META-INF 目錄,它用于存儲(chǔ)包和擴(kuò)展的配置數(shù)據(jù),如安全性和版本信息。Java 2 平臺(tái)識(shí)別并解釋 META-INF 目錄中的下述文件和目錄,以便配置應(yīng)用程序、擴(kuò)展和類裝載器:

      ☆ MANIFEST.MF。 這個(gè) manifest 文件定義了與擴(kuò)展和包相關(guān)的數(shù)據(jù)。

      ☆ INDEX.LIST。 這個(gè)文件由 jar 工具的新選項(xiàng) -i 生成,它包含在應(yīng)用程序或者擴(kuò)展中定義的包的位置信息。它是 JarIndex 實(shí)現(xiàn)的一部分,并由類裝載器用于加速類裝載過(guò)程。

      ☆ xxx.SF。 這是 JAR 文件的簽名文件。占位符 xxx 標(biāo)識(shí)了簽名者。

      ☆ xxx.DSA。 與簽名文件相關(guān)聯(lián)的簽名程序塊文件,它存儲(chǔ)了用于簽名 JAR 文件的公共簽名。

      jar 工具
      為了用 JAR 文件執(zhí)行基本的任務(wù),要使用作為Java Development Kit 的一部分提供的 Java Archive Tool (jar 工具)。用 jar 命令調(diào)用 jar 工具。表 1 顯示了一些常見(jiàn)的應(yīng)用:

    表 1. 常見(jiàn)的 jar 工具用法
    功能 命令
    用一個(gè)單獨(dú)的文件創(chuàng)建一個(gè) JAR 文件 jar cf jar-file input-file...
    用一個(gè)目錄創(chuàng)建一個(gè) JAR 文件 jar cf jar-file dir-name
    創(chuàng)建一個(gè)未壓縮的 JAR 文件 jar cf0 jar-file dir-name
    更新一個(gè) JAR 文件 jar uf jar-file input-file...
    查看一個(gè) JAR 文件的內(nèi)容 jar tf jar-file
    提取一個(gè) JAR 文件的內(nèi)容 jar xf jar-file
    從一個(gè) JAR 文件中提取特定的文件 jar xf jar-file archived-file...
    運(yùn)行一個(gè)打包為可執(zhí)行 JAR 文件的應(yīng)用程序 java -jar app.jar

      可執(zhí)行的 JAR
      一個(gè)可執(zhí)行的 jar 文件是一個(gè)自包含的 Java 應(yīng)用程序,它存儲(chǔ)在特別配置的JAR 文件中,可以由 JVM 直接執(zhí)行它而無(wú)需事先提取文件或者設(shè)置類路徑。要運(yùn)行存儲(chǔ)在非可執(zhí)行的 JAR 中的應(yīng)用程序,必須將它加入到您的類路徑中,并用名字調(diào)用應(yīng)用程序的主類。但是使用可執(zhí)行的 JAR 文件,我們可以不用提取它或者知道主要入口點(diǎn)就可以運(yùn)行一個(gè)應(yīng)用程序。可執(zhí)行 JAR 有助于方便發(fā)布和執(zhí)行 Java 應(yīng)用程序。

      創(chuàng)建可執(zhí)行 JAR
      創(chuàng)建一個(gè)可執(zhí)行 JAR 很容易。首先將所有應(yīng)用程序代碼放到一個(gè)目錄中。假設(shè)應(yīng)用程序中的主類是 com.mycompany.myapp.Sample。您要?jiǎng)?chuàng)建一個(gè)包含應(yīng)用程序代碼的 JAR 文件并標(biāo)識(shí)出主類。為此,在某個(gè)位置(不是在應(yīng)用程序目錄中)創(chuàng)建一個(gè)名為 manifest 的文件,并在其中加入以下一行:

      Main-Class: com.mycompany.myapp.Sample

      然后,像這樣創(chuàng)建 JAR 文件:

      jar cmf manifest ExecutableJar.jar application-dir

      所要做的就是這些了 -- 現(xiàn)在可以用 java -jar 執(zhí)行這個(gè) JAR 文件 ExecutableJar.jar。

      一個(gè)可執(zhí)行的 JAR 必須通過(guò) menifest 文件的頭引用它所需要的所有其他從屬 JAR。如果使用了 -jar 選項(xiàng),那么環(huán)境變量 CLASSPATH 和在命令行中指定的所有類路徑都被 JVM 所忽略。

      啟動(dòng)可執(zhí)行 JAR
      既然我們已經(jīng)將自己的應(yīng)用程序打包到了一個(gè)名為 ExecutableJar.jar 的可執(zhí)行 JAR 中了,那么我們就可以用下面的命令直接從文件啟動(dòng)這個(gè)應(yīng)用程序:

      java -jar ExecutableJar.jar

      包密封
      密封 JAR 文件中的一個(gè)包意味著在這個(gè)包中定義的所有類都必須在同一個(gè) JAR 文件中找到。這使包的作者可以增強(qiáng)打包類之間的版本一致性。密封還提供了防止代碼篡改的手段。

      要密封包,需要在 JAR 的 manifest 文件中為包添加一個(gè) Name 頭,然后加上值為“true”的 Sealed 頭。與可執(zhí)行的 JAR 一樣,可以在創(chuàng)建 JAR 時(shí),通過(guò)指定一個(gè)具有適當(dāng)頭元素的 manifest 文件密封一個(gè) JAR,如下所示:

      Name: com/samplePackage/
      Sealed: true

      Name 頭標(biāo)識(shí)出包的相對(duì)路徑名。它以一個(gè)“/”結(jié)束以與文件名區(qū)別。在 Name 頭后面第一個(gè)空行之前的所有頭都作用于在 Name 頭中指定的文件或者包。在上述例子中,因?yàn)?Sealed 頭出現(xiàn)在 Name 頭后并且中間沒(méi)有空行,所以 Sealed 頭將被解釋為只應(yīng)用到包 com/samplePackage 上。

      如果試圖從密封包所在的 JAR 文件以外的其他地方裝載密封包中的一個(gè)類,那么 JVM 將拋出一個(gè) SecurityException。

      擴(kuò)展打包
      擴(kuò)展為 Java 平臺(tái)增加了功能,在 JAR 文件格式中已經(jīng)加入了擴(kuò)展機(jī)制。擴(kuò)展機(jī)制使得 JAR 文件可以通過(guò) manifest 文件中的 Class-Path 頭指定所需要的其他 JAR 文件。

      假設(shè) extension1.jar 和 extension2.jar 是同一個(gè)目錄中的兩個(gè) JAR 文件,extension1.jar 的 manifest 文件包含以下頭:

      Class-Path: extension2.jar

      這個(gè)頭表明 extension2.jar 中的類是 extension1.jar 中的類的擴(kuò)展類。extension1.jar 中的類可以調(diào)用 extension2.jar 中的類,并且不要求 extension2.jar 處在類路徑中。

      在裝載使用擴(kuò)展機(jī)制的 JAR 時(shí),JVM 會(huì)高效而自動(dòng)地將在Class-Path 頭中引用的 JAR 添加到類路徑中。不過(guò),擴(kuò)展 JAR 路徑被解釋為相對(duì)路徑,所以一般來(lái)說(shuō),擴(kuò)展 JAR 必須存儲(chǔ)在引用它的 JAR 所在的同一目錄中。

      例如,假設(shè)類 ExtensionClient 引用了類 ExtensionDemo,它捆綁在一個(gè)名為 ExtensionClient.jar 的 JAR 文件中,而類 ExtensionDemo 則捆綁在 ExtensionDemo.jar 中。為了使 ExtensionDemo.jar 可以成為擴(kuò)展,必須將 ExtensionDemo.jar 列在 ExtensionClient.jar 的 manifest 的 Class-Path 頭中,如下所示:

      Manifest-Version: 1.0
      Class-Path: ExtensionDemo.jar

      在這個(gè) manifest 中 Class-Path 頭的值是沒(méi)有指定路徑的 ExtensionDemo.jar,表明 ExtensionDemo.jar 與 ExtensionClient JAR 文件處在同一目錄中。

      JAR 文件中的安全性
      JAR 文件可以用 jarsigner 工具或者直接通過(guò) java.security API 簽名。一個(gè)簽名的 JAR 文件與原來(lái)的 JAR 文件完全相同,只是更新了它的 manifest,并在 META-INF 目錄中增加了兩個(gè)文件,一個(gè)簽名文件和一個(gè)簽名塊文件。

      JAR 文件是用一個(gè)存儲(chǔ)在 Keystore 數(shù)據(jù)庫(kù)中的證書(shū)簽名的。存儲(chǔ)在 keystore 中的證書(shū)有密碼保護(hù),必須向 jarsigner 工具提供這個(gè)密碼才能對(duì) JAR 文件簽名。


    Keystore 數(shù)據(jù)庫(kù)

      JAR 的每一位簽名者都由在 JAR 文件的 META-INF 目錄中的一個(gè)具有 .SF 擴(kuò)展名的簽名文件表示。這個(gè)文件的格式類似于 manifest 文件 -- 一組 RFC-822 頭。如下所示,它的組成包括一個(gè)主要部分,它包括了由簽名者提供的信息、但是不特別針對(duì)任何特定的 JAR 文件項(xiàng),還有一系列的單獨(dú)的項(xiàng),這些項(xiàng)也必須包含在 menifest 文件中。在驗(yàn)證一個(gè)簽名的 JAR 時(shí),將簽名文件的摘要值與對(duì) JAR 文件中的相應(yīng)項(xiàng)計(jì)算的摘要值進(jìn)行比較。

      清單 1. 簽名 JAR 中的 Manifest 和 signature 文件

    Contents of signature file META-INF/MANIFEST.MF

    Manifest-Version: 1.0
    Created-By: 1.3.0 (Sun Microsystems Inc.)

    Name: Sample.java
    SHA1-Digest: 3+DdYW8INICtyG8ZarHlFxX0W6g=

    Name: Sample.class
    SHA1-Digest: YJ5yQHBZBJ3SsTNcHJFqUkfWEmI=

    Contents of signature file META-INF/JAMES.SF

    Signature-Version: 1.0
    SHA1-Digest-Manifest: HBstZOJBuuTJ6QMIdB90T8sjaOM=
    Created-By: 1.3.0 (Sun Microsystems Inc.)

    Name: Sample.java
    SHA1-Digest: qipMDrkurQcKwnyIlI3Jtrnia8Q=

    Name: Sample.class
    SHA1-Digest: pT2DYby8QXPcCzv2NwpLxd8p4G4=

      數(shù)字簽名
      一個(gè)數(shù)字簽名是.SF 簽名文件的已簽名版本。數(shù)字簽名文件是二進(jìn)制文件,并且與 .SF 文件有相同的文件名,但是擴(kuò)展名不同。根據(jù)數(shù)字簽名的類型 -- RSA、DSA 或者 PGP -- 以及用于簽名 JAR 的證書(shū)類型而有不同的擴(kuò)展名。

      Keystore
      要簽名一個(gè) JAR 文件,必須首先有一個(gè)私鑰。私鑰及其相關(guān)的公鑰證書(shū)存儲(chǔ)在名為 keystores 的、有密碼保護(hù)的數(shù)據(jù)庫(kù)中。JDK 包含創(chuàng)建和修改 keystores 的工具。keystore 中的每一個(gè)密鑰都可以用一個(gè)別名標(biāo)識(shí),它通常是擁有這個(gè)密鑰的簽名者的名字。

      所有 keystore 項(xiàng)(密鑰和信任的證書(shū)項(xiàng))都是用唯一別名訪問(wèn)的。別名是在用 keytool -genkey 命令生成密鑰對(duì)(公鑰和私鑰)并在 keystore 中添加項(xiàng)時(shí)指定的。之后的 keytool 命令必須使用同樣的別名引用這一項(xiàng)。

      例如,要用別名“james”生成一個(gè)新的公鑰/私鑰對(duì)并將公鑰包裝到自簽名的證書(shū)中,要使用下述命令:

    keytool -genkey -alias james -keypass jamespass
            -validity 80 -keystore jamesKeyStore
            -storepass jamesKeyStorePass

      這個(gè)命令序列指定了一個(gè)初始密碼“jamespass”,后續(xù)的命令在訪問(wèn) keystore “jamesKeyStore”中與別名“james”相關(guān)聯(lián)的私鑰時(shí),就需要這個(gè)密碼。如果 keystore“jamesKeyStore”不存在,則 keytool 會(huì)自動(dòng)創(chuàng)建它。

      jarsigner 工具
      jarsigner 工具使用 keystore 生成或者驗(yàn)證 JAR 文件的數(shù)字簽名。

      假設(shè)像上述例子那樣創(chuàng)建了 keystore “jamesKeyStore”,并且它包含一個(gè)別名為“james”的密鑰,可以用下面的命令簽名一個(gè) JAR 文件:

    jarsigner -keystore jamesKeyStore -storepass jamesKeyStorePass
              -keypass jamespass -signedjar SSample.jar Sample.jar james

      這個(gè)命令用密碼“jamesKeyStorePass”從名為“jamesKeyStore”的 keystore 中提出別名為“james”、密碼為“jamespass”的密鑰,并對(duì) Sample.jar 文件簽名、創(chuàng)建一個(gè)簽名的 JAR -- SSample.jar。

      jarsigner 工具還可以驗(yàn)證一個(gè)簽名的 JAR 文件,這種操作比簽名 JAR 文件要簡(jiǎn)單得多,只需執(zhí)行以下命令:

      jarsigner -verify SSample.jar

      如果簽名的 JAR 文件沒(méi)有被篡改過(guò),那么 jarsigner 工具就會(huì)告訴您 JAR 通過(guò)驗(yàn)證了。否則,它會(huì)拋出一個(gè) SecurityException, 表明哪些文件沒(méi)有通過(guò)驗(yàn)證。

      還可以用 java.util.jar 和 java.security API 以編程方式簽名 JAR(有關(guān)細(xì)節(jié)參閱參考資料)。也可以使用像 Netscape Object Signing Tool 這樣的工具。

      JAR 索引
      如果一個(gè)應(yīng)用程序或者 applet 捆綁到多個(gè) JAR 文件中,那么類裝載器就使用一個(gè)簡(jiǎn)單的線性搜索算法搜索類路徑中的每一個(gè)元素,這使類裝載器可能要下載并打開(kāi)許多個(gè) JAR 文件,直到找到所要的類或者資源。如果類裝載器試圖尋找一個(gè)不存在的資源,那么在應(yīng)用程序或者 applet 中的所有 JAR 文件都會(huì)下載。對(duì)于大型的網(wǎng)絡(luò)應(yīng)用程序和 applet,這會(huì)導(dǎo)致啟動(dòng)緩慢、響應(yīng)遲緩并浪費(fèi)帶寬。

      從 JDK 1.3 以后,JAR 文件格式開(kāi)始支持索引以優(yōu)化網(wǎng)絡(luò)應(yīng)用程序中類的搜索過(guò)程,特別是 applet。JarIndex 機(jī)制收集在 applet 或者應(yīng)用程序中定義的所有 JAR 文件的內(nèi)容,并將這些信息存儲(chǔ)到第一個(gè) JAR 文件中的索引文件中。下載了第一個(gè) JAR 文件后,applet 類裝載器將使用收集的內(nèi)容信息高效地裝載 JAR 文件。這個(gè)目錄信息存儲(chǔ)在根 JAR 文件的 META-INF 目錄中的一個(gè)名為 INDEX.LIST 的簡(jiǎn)單文本文件中。

      創(chuàng)建一個(gè) JarIndex
      可以通過(guò)在 jar 命令中指定 -i 選項(xiàng)創(chuàng)建一個(gè) JarIndex。假設(shè)我們的目錄結(jié)構(gòu)如下圖所示:


    JarIndex

      您將使用下述命令為 JarIndex_Main.jar、JarIndex_test.jar 和 JarIndex_test1.jar 創(chuàng)建一個(gè)索引文件:

      jar -i JarIndex_Main.jar JarIndex_test.jar SampleDir/JarIndex_test1.jar

      INDEX.LIST 文件的格式很簡(jiǎn)單,包含每個(gè)已索引的 JAR 文件中包含的包或者類的名字,如清單 2 所示:

      清單 2. JarIndex INDEX.LIST 文件示例

    JarIndex-Version: 1.0

    JarIndex_Main.jar
    sp

    JarIndex_test.jar
    Sample

    SampleDir/JarIndex_test1.jar
    org
    org/apache
    org/apache/xerces
    org/apache/xerces/framework
    org/apache/xerces/framework/xml4j

      結(jié)束語(yǔ)
      JAR 格式遠(yuǎn)遠(yuǎn)超出了一種壓縮格式,它有許多可以改進(jìn)效率、安全性和組織 Java 應(yīng)用程序的功能。因?yàn)檫@些功能已經(jīng)建立在核心平臺(tái) -- 包括編譯器和類裝載器 -- 中了,所以開(kāi)發(fā)人員可以利用 JAR 文件格式的能力簡(jiǎn)化和改進(jìn)開(kāi)發(fā)和部署過(guò)程。



    轉(zhuǎn)自:http://linxh.bokee.com/2946294.html

    posted @ 2008-05-23 11:08 心。 閱讀(419) | 評(píng)論 (0)編輯 收藏
            1、禁用壓縮文件夾功能
      假如你打開(kāi)zip文件的話用winzip或者winrar軟件的話,以下優(yōu)化是一個(gè)相當(dāng)好的優(yōu)化,Windows XP內(nèi)置了對(duì)ZIP文件的,我們可以把zip文件當(dāng)成文件夾瀏覽。不過(guò),系統(tǒng)要使用部分資源來(lái)實(shí)現(xiàn) 這一功能,因此禁用這一功能可以提升系統(tǒng)性能。實(shí)現(xiàn)方法非常簡(jiǎn)單,只需取消zipfldr.dll的注冊(cè)就可以了。
      開(kāi)始→運(yùn)行: regsvr32 /u zipfldr.dll

      2、減少開(kāi)機(jī)磁盤(pán)掃描等待時(shí)間,重啟時(shí)候馬上你會(huì)看到效果。
      開(kāi)始→運(yùn)行:chkntfs /t:0

      3、刪除系統(tǒng)備份文件,在各種軟硬件安裝妥當(dāng)之后,其實(shí)XP需要更新文件的時(shí)候就很少了。
      開(kāi)始→運(yùn)行:sfc.exe /purgecache
      然后回車即可,可節(jié)省百兆。
      假如擔(dān)心的話,可不執(zhí)行,此做法只會(huì)節(jié)省空間,而不是加速。

      4、開(kāi)始→運(yùn)行: services.msc進(jìn)入XP自帶服務(wù)修改列表
      在列表每個(gè)服務(wù)的屬性里可選"關(guān)閉","手動(dòng)","自動(dòng)"。

      alerter -錯(cuò)誤警報(bào)器。 (可關(guān)閉)

      application layer gateway service -給與第三者網(wǎng)絡(luò)共享/防火墻支持的服務(wù),有些防火墻/網(wǎng)絡(luò)共享軟件需要。占用1。5mb內(nèi)存。 (可關(guān)閉)

      application management-用于設(shè)定,發(fā)布和刪除軟件服務(wù)。

      automatic updates -windows自動(dòng)更新。(可關(guān)閉)

      background intelligent transfer service - 這個(gè)服務(wù)原是用來(lái)實(shí)現(xiàn)http1.1服務(wù)器之間的信息傳輸,微軟稱支持windows更新時(shí)斷點(diǎn)續(xù)傳

      clipbook - 用與局域網(wǎng)電腦來(lái)共享 粘貼/剪貼的內(nèi)容。(可關(guān)閉)

      com+Event system -一些 COM+ 軟件需要。(檢查你的 c:program filesComPlus Applications 目錄,沒(méi)東西可以把這個(gè)服務(wù)關(guān)閉)

      COM+Event system application -同上 (可關(guān)閉)

      COmputer browser -用來(lái)瀏覽局域網(wǎng)電腦的服務(wù),但關(guān)了也不影響瀏覽!(可關(guān)閉)

      cryptographic services -windows更新時(shí)用來(lái)確認(rèn)windows 文件指紋的,我更新時(shí)才開(kāi)啟一下。 (可關(guān)閉)

      DHCP client-靜態(tài)IP者需要(xDSL 等)。

      Distributed link tracking client-用于局域網(wǎng)更新連接信息,比如在電腦A有個(gè)文件,在B做了個(gè)連接,如果文件移動(dòng)了,這個(gè)服務(wù)將會(huì)更新信息。占用4兆內(nèi)存。 (可關(guān)閉) 

            Distributed Transaction coordinator-無(wú)聊的東西。 (可關(guān)閉)

      DNS Client-DNS解析服務(wù)。(可關(guān)閉)

      Error reporting service -錯(cuò)誤報(bào)告器,把windows中錯(cuò)誤報(bào)告給微軟。(可關(guān)閉)

      Event Log- 系統(tǒng)日志紀(jì)錄服務(wù),很有用于查找系統(tǒng)毛病.

      Fast user switching compatibility-多用戶快速切換服務(wù)。(可關(guān)閉)

      help and support -幫助。(可關(guān)閉)

      Human interface device access-支持"弱智"電腦配件的。比如鍵盤(pán)上調(diào)音量的按鈕等等。(可關(guān)閉)

      IMAPI CD-burning COM service -xp刻牒服務(wù),用軟件就不用了。占用1.6兆內(nèi)存 (可關(guān)閉)

      Indexing service -恐怖的xp減速……(可關(guān)閉)

      Internet Connection Firewall(ICF)……-xp防火墻。(不用的話可關(guān)閉)

      IPSEC Services-大眾用戶連邊都沾不上。 (可關(guān)閉)

      Logical Disk manager -磁盤(pán)管理服務(wù)。需要時(shí)它會(huì)通知你,所以一般關(guān)。 (可關(guān)閉)

      Logical Disk manager administrative service-同上。 (可關(guān)閉)

      messenger -不是msn,不想被騷擾的話就關(guān)。注:妖刺就是利用這個(gè)。 (可關(guān)閉)

      MS software shadow copy provider-無(wú)用,據(jù)說(shuō)是備份用的。但……沒(méi)用。 (可關(guān)閉)

      Net Logon-登陸Domain Controller用的。(可關(guān)閉)

      Netmeeting remote desktop sharing-用netmeeting實(shí)現(xiàn)電腦共享。(可關(guān)閉)

      Network Connections - 上網(wǎng)/局域網(wǎng)要用的。

      Network DDE -和clipbook一起用的。(可關(guān)閉)

      Network DDE DSDM -同上 (可關(guān)閉)

      Network Location Awareness-如有網(wǎng)絡(luò)共享或ICS/ICF可能需要。(服務(wù)器端) (可關(guān)閉)

      NT LM Security support provider-telnet 服務(wù)用的。(可關(guān)閉)

      NVIDIA Driver Helper service -nvidia 顯卡幫助。(可關(guān)閉)

      PDEngine - perfectdisk 引擎

      PDScheduler -perfectdisk 計(jì)劃服務(wù)

      PerFORMance logs and alerts-記錄機(jī)器運(yùn)行狀況而且定時(shí)寫(xiě)入日志或發(fā)警告,內(nèi)容可能過(guò)于專業(yè),所以自己決定。

      Plug and Play- 自動(dòng)查測(cè)新裝硬件,即插即用。

      Portable media serial number-絕對(duì)無(wú)用。 (可關(guān)閉)

      Print Spooler -打印機(jī)用的。 (無(wú)打印機(jī)可關(guān)閉)

      Protected Storage-儲(chǔ)存本地密碼和網(wǎng)上服務(wù)密碼的服務(wù),包括填表時(shí)的"自動(dòng)完成"功能。

      QoS RSVP -據(jù)說(shuō)是降低網(wǎng)速20%……(可關(guān)閉)

      Remote access auto connection manager-寬帶/網(wǎng)絡(luò)共享。

      Remote desktop help session manager-遠(yuǎn)程幫助服務(wù),占用4兆內(nèi)存。 (可關(guān)閉)

      Remote Procedure Call (RPC) -系統(tǒng)核心服務(wù)。

      Remote Procedure Call LOCATOR-這個(gè)倒沒(méi)什么用,管理 RPC 數(shù)據(jù)庫(kù)服務(wù),占用1兆內(nèi)存。 (可關(guān)閉)

      remote registry -遠(yuǎn)程注冊(cè)表運(yùn)行/修改。微軟的漏洞……(可關(guān)閉)

      removable storage -一般情況下不用,磁帶備份用的。 (可關(guān)閉)

      routing and remote access-不知者關(guān),我也不知。 (可關(guān)閉)

      secondary logon-給與administrator 以外的用戶分配指定操作權(quán).(可關(guān)閉)

      security accounts manager-像 Protected Storage, IIS Admin 才需要。

      server -局域網(wǎng)文件/打印共享需要的。 (不打印者可關(guān)閉)

      shell hardware detection-給有些配置自動(dòng)啟動(dòng),像內(nèi)存棒,和有些cd驅(qū)動(dòng)等

      smart card -占1.4兆內(nèi)存呢(可關(guān)閉)

      smart card helper -關(guān)。(可關(guān)閉)

      SSDP Discovery service-沒(méi)有什么硬件利用這個(gè)服務(wù)。(可關(guān)閉)

      system event notification-記錄用戶登錄/注銷/重起/關(guān)機(jī)信息。(可關(guān)閉)

      system restore service -系統(tǒng)還原服務(wù),吃資源和內(nèi)存的怪獸。雖然有時(shí)用到,自己決定。 (可關(guān)閉)

      task scheduler-windows 計(jì)劃服務(wù)。(可關(guān)閉)

      TCP/IP NetBIOS helper-如果你的網(wǎng)絡(luò)不用Netbios 或WINS的話。(可關(guān)閉)

      Telephony - 撥號(hào)服務(wù),如果你的寬帶不用撥號(hào),那么關(guān)了它。

      telnet -還是微軟的漏洞。這根dos中的telnet命令沒(méi)關(guān)系。2兆內(nèi)存。(可關(guān)閉)

      terminal services-實(shí)現(xiàn)遠(yuǎn)程登錄本地電腦,快速用戶切換和遠(yuǎn)程桌面功能需要,不用這些功能就關(guān)了吧。(可關(guān)閉)

      themes -XP的主題。關(guān)閉后是XP的經(jīng)典風(fēng)格。(可關(guān)閉)

      uninterruptible power supply-停電保護(hù)設(shè)備用的。(可關(guān)閉)

      universal plug and play device host-同SSDP Discovery Service。(可關(guān)閉)

      upload manager-用來(lái)實(shí)現(xiàn)服務(wù)器和客戶端輸送文件的服務(wù),簡(jiǎn)單文件傳輸不需要這個(gè)。(可關(guān)閉)

      volume shadow copy-同MS Software Shadow Copy Provider,無(wú)用。(可關(guān)閉)

      webclient-可能和以后的.net技術(shù)有聯(lián)系。(可關(guān)閉)

      Windows Audio - 控制著你聽(tīng)到的聲音。(喜歡無(wú)聲者可關(guān)閉)

      Windows Installer -windows的MSI安裝服務(wù)。(建議設(shè)成手動(dòng))

      windows image acquisition (WIA) -有些數(shù)碼相機(jī)和掃描器用的,覺(jué)得沒(méi)用。(可關(guān)閉)

      Windows Management Instrumentation - 重要的服務(wù),關(guān)了會(huì)出現(xiàn)奇怪的問(wèn)題
    posted @ 2007-12-08 00:20 心。 閱讀(3540) | 評(píng)論 (0)編輯 收藏

    Thread.currentThread().getContextClassLoader().getResource("")
    Test.class.getClassLoader().getResource("")
    ClassLoader.getSystemResource("")
    Test.class.getResource("")
    Test.class.getResource("/")
    new File("/").getAbsolutePath()
    System.getProperty("user.dir")

    關(guān)于Classloader詳見(jiàn)http://www.tkk7.com/lengxinCEO/archive/2007/12/07/166055.html

    posted @ 2007-12-07 15:25 心。 閱讀(1285) | 評(píng)論 (0)編輯 收藏

    當(dāng)JVM(Java虛擬機(jī))啟動(dòng)時(shí),會(huì)形成由三個(gè)類加載器組成的初始類加載器層次結(jié)構(gòu):

           bootstrap classloader
                    |
           extension classloader
                    |
           system classloader

    bootstrap classloader -引導(dǎo)(也稱為原始)類加載器,它負(fù)責(zé)加載Java的核心類。在Sun的JVM中,在執(zhí)行java的命令中使用-Xbootclasspath選項(xiàng)或使用 - D選項(xiàng)指定sun.boot.class.path系統(tǒng)屬性值可以指定附加的類。這個(gè)加載器的是非常特殊的,它實(shí)際上不是 java.lang.ClassLoader的子類,而是由JVM自身實(shí)現(xiàn)的。大家可以通過(guò)執(zhí)行以下代碼來(lái)獲得bootstrap classloader加載了那些核心類庫(kù):
            URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
            for (int i = 0; i < urls.length; i++) {
                System.out.println(urls[i].toExternalForm());
            }
    在我的計(jì)算機(jī)上的結(jié)果為:
    文件:/C:/j2sdk1.4.1_01/jre/lib/endorsed/dom.jar
    文件:/C:/j2sdk1.4.1_01/jre/lib/endorsed/sax.jar
    文件:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xalan-2.3.1.jar
    文件:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xercesImpl-2.0.0.jar
    文件:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xml-apis.jar
    文件:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xsltc.jar
    文件:/C:/j2sdk1.4.1_01/jre/lib/rt.jar
    文件:/C:/j2sdk1.4.1_01/jre/lib/i18n.jar
    文件:/C:/j2sdk1.4.1_01/jre/lib/sunrsasign.jar
    文件:/C:/j2sdk1.4.1_01/jre/lib/jsse.jar
    文件:/C:/j2sdk1.4.1_01/jre/lib/jce.jar
    文件:/C:/j2sdk1.4.1_01/jre/lib/charsets.jar
    文件:/C:/j2sdk1.4.1_01/jre/classes
    這時(shí)大家知道了為什么我們不需要在系統(tǒng)屬性CLASSPATH中指定這些類庫(kù)了吧,因?yàn)镴VM在啟動(dòng)的時(shí)候就自動(dòng)加載它們了。

    extension classloader -擴(kuò)展類加載器,它負(fù)責(zé)加載JRE的擴(kuò)展目錄(JAVA_HOME/jre/lib/ext或者由java.ext.dirs系統(tǒng)屬性指定的)中JAR的類包。這為引入除Java核心類以外的新功能提供了一個(gè)標(biāo)準(zhǔn)機(jī)制。因?yàn)槟J(rèn)的擴(kuò)展目錄對(duì)所有從同一個(gè)JRE中啟動(dòng)的JVM都是通用的,所以放入這個(gè)目錄的 JAR類包對(duì)所有的JVM和system classloader都是可見(jiàn)的。在這個(gè)實(shí)例上調(diào)用方法getParent()總是返回空值null,因?yàn)橐龑?dǎo)加載器bootstrap classloader不是一個(gè)真正的ClassLoader實(shí)例。所以當(dāng)大家執(zhí)行以下代碼時(shí):
       System.out.println(System.getProperty("java.ext.dirs"));
       ClassLoader extensionClassloader=ClassLoader.getSystemClassLoader().getParent();
       System.out.println("the parent of extension classloader : "+extensionClassloader.getParent());
    結(jié)果為:
    C:\j2sdk1.4.1_01\jre\lib\ext
    the parent of extension classloader : null
    extension classloader是system classloader的parent,而bootstrap classloader是extension classloader的parent,但它不是一個(gè)實(shí)際的classloader,所以為null。

    system classloader -系統(tǒng)(也稱為應(yīng)用)類加載器,它負(fù)責(zé)在JVM被啟動(dòng)時(shí),加載來(lái)自在命令java中的-classpath或者java.class.path系統(tǒng)屬性或者 CLASSPATH*作系統(tǒng)屬性所指定的JAR類包和類路徑。總能通過(guò)靜態(tài)方法ClassLoader.getSystemClassLoader()找到該類加載器。如果沒(méi)有特別指定,則用戶自定義的任何類加載器都將該類加載器作為它的父加載器。執(zhí)行以下代碼即可獲得:
       System.out.println(System.getProperty("java.class.path"));
    輸出結(jié)果則為用戶在系統(tǒng)屬性里面設(shè)置的CLASSPATH。
    classloader 加載類用的是全盤(pán)負(fù)責(zé)委托機(jī)制。所謂全盤(pán)負(fù)責(zé),即是當(dāng)一個(gè)classloader加載一個(gè)Class的時(shí)候,這個(gè)Class所依賴的和引用的所有 Class也由這個(gè)classloader負(fù)責(zé)載入,除非是顯式的使用另外一個(gè)classloader載入;委托機(jī)制則是先讓parent(父)類加載器 (而不是super,它與parent classloader類不是繼承關(guān)系)尋找,只有在parent找不到的時(shí)候才從自己的類路徑中去尋找。此外類加載還采用了cache機(jī)制,也就是如果 cache中保存了這個(gè)Class就直接返回它,如果沒(méi)有才從文件中讀取和轉(zhuǎn)換成Class,并存入cache,這就是為什么我們修改了Class但是必須重新啟動(dòng)JVM才能生效的原因。

    每個(gè)ClassLoader加載Class的過(guò)程是:
    1.檢測(cè)此Class是否載入過(guò)(即在cache中是否有此Class),如果有到8,如果沒(méi)有到2
    2.如果parent classloader不存在(沒(méi)有parent,那parent一定是bootstrap classloader了),到4
    3.請(qǐng)求parent classloader載入,如果成功到8,不成功到5
    4.請(qǐng)求jvm從bootstrap classloader中載入,如果成功到8
    5.尋找Class文件(從與此classloader相關(guān)的類路徑中尋找)。如果找不到則到7.
    6.從文件中載入Class,到8.
    7.拋出ClassNotFoundException.
    8.返回Class.

    其中5.6步我們可以通過(guò)覆蓋ClassLoader的findClass方法來(lái)實(shí)現(xiàn)自己的載入策略。甚至覆蓋loadClass方法來(lái)實(shí)現(xiàn)自己的載入過(guò)程。

    類加載器的順序是:
    先是bootstrap classloader,然后是extension classloader,最后才是system classloader。大家會(huì)發(fā)現(xiàn)加載的Class越是重要的越在靠前面。這樣做的原因是出于安全性的考慮,試想如果system classloader“親自”加載了一個(gè)具有破壞性的“java.lang.System”類的后果吧。這種委托機(jī)制保證了用戶即使具有一個(gè)這樣的類,也把它加入到了類路徑中,但是它永遠(yuǎn)不會(huì)被載入,因?yàn)檫@個(gè)類總是由bootstrap classloader來(lái)加載的。大家可以執(zhí)行一下以下的代碼:
       System.out.println(System.class.getClassLoader());
    將會(huì)看到結(jié)果是null,這就表明java.lang.System是由bootstrap classloader加載的,因?yàn)閎ootstrap classloader不是一個(gè)真正的ClassLoader實(shí)例,而是由JVM實(shí)現(xiàn)的,正如前面已經(jīng)說(shuō)過(guò)的。

    下面就讓我們來(lái)看看JVM是如何來(lái)為我們來(lái)建立類加載器的結(jié)構(gòu)的:
    sun.misc.Launcher,顧名思義,當(dāng)你執(zhí)行java命令的時(shí)候,JVM會(huì)先使用bootstrap classloader載入并初始化一個(gè)Launcher,執(zhí)行下來(lái)代碼:
      System.out.println("the Launcher's classloader is "+sun.misc.Launcher.getLauncher().getClass().getClassLoader());
    結(jié)果為:
      the Launcher's classloader is null (因?yàn)槭怯胋ootstrap classloader加載,所以class loader為null)
    Launcher 會(huì)根據(jù)系統(tǒng)和命令設(shè)定初始化好class loader結(jié)構(gòu),JVM就用它來(lái)獲得extension classloader和system classloader,并載入所有的需要載入的Class,最后執(zhí)行java命令指定的帶有靜態(tài)的main方法的Class。extension classloader實(shí)際上是sun.misc.Launcher$ExtClassLoader類的一個(gè)實(shí)例,system classloader實(shí)際上是sun.misc.Launcher$AppClassLoader類的一個(gè)實(shí)例。并且都是 java.net.URLClassLoader的子類。

    讓我們來(lái)看看Launcher初試化的過(guò)程的部分代碼。

    Launcher的部分代碼:
    public class Launcher  {
       public Launcher() {
           ExtClassLoader extclassloader;
           try {
               //初始化extension classloader
               extclassloader = ExtClassLoader.getExtClassLoader();
           } catch(IOException ioexception) {
               throw new InternalError("Could not create extension class loader");
           }
           try {
               //初始化system classloader,parent是extension classloader
               loader = AppClassLoader.getAppClassLoader(extclassloader);
           } catch(IOException ioexception1) {
               throw new InternalError("Could not create application class loader");
           }
           //將system classloader設(shè)置成當(dāng)前線程的context classloader(將在后面加以介紹)
           Thread.currentThread().setContextClassLoader(loader);
           ......
       }
       public ClassLoader getClassLoader() {
           //返回system classloader
           return loader;
       }
    }

    extension classloader的部分代碼:
    static class Launcher$ExtClassLoader extends URLClassLoader {

       public static Launcher$ExtClassLoader getExtClassLoader()
           throws IOException
       {
           File afile[] = getExtDirs();
           return (Launcher$ExtClassLoader)AccessController.doPrivileged(new Launcher$1(afile));
       }
      private static File[] getExtDirs() {
           //獲得系統(tǒng)屬性“java.ext.dirs”
           String s = System.getProperty("java.ext.dirs");
           File afile[];
           if(s != null) {
               StringTokenizer stringtokenizer = new StringTokenizer(s, File.pathSeparator);
               int i = stringtokenizer.countTokens();
               afile = new File;
               for(int j = 0; j < i; j++)
                   afile[j] = new File(stringtokenizer.nextToken());

           } else {
               afile = new File[0];
           }
           return afile;
       }
    }

    system classloader的部分代碼:
    static class Launcher$AppClassLoader extends URLClassLoader
    {

       public static ClassLoader getAppClassLoader(ClassLoader classloader)
           throws IOException
       {
           //獲得系統(tǒng)屬性“java.class.path”
           String s = System.getProperty("java.class.path");
           File afile[] = s != null ? Launcher.access$200(s) : new File[0];
           return (Launcher$AppClassLoader)AccessController.doPrivileged(new Launcher$2(s, afile, classloader));
       }
    }

    看了源代碼大家就清楚了吧,extension classloader是使用系統(tǒng)屬性“java.ext.dirs”設(shè)置類搜索路徑的,并且沒(méi)有parent。system classloader是使用系統(tǒng)屬性“java.class.path”設(shè)置類搜索路徑的,并且有一個(gè)parent classloader。Launcher初始化extension classloader,system classloader,并將system classloader設(shè)置成為context classloader,但是僅僅返回system classloader給JVM。

      這里怎么又出來(lái)一個(gè)context classloader呢?它有什么用呢?我們?cè)诮⒁粋€(gè)線程Thread的時(shí)候,可以為這個(gè)線程通過(guò)setContextClassLoader方法來(lái)指定一個(gè)合適的classloader作為這個(gè)線程的context classloader,當(dāng)此線程運(yùn)行的時(shí)候,我們可以通過(guò)getContextClassLoader方法來(lái)獲得此context classloader,就可以用它來(lái)載入我們所需要的Class。默認(rèn)的是system classloader。利用這個(gè)特性,我們可以“打破”classloader委托機(jī)制了,父classloader可以獲得當(dāng)前線程的context classloader,而這個(gè)context classloader可以是它的子classloader或者其他的classloader,那么父classloader就可以從其獲得所需的 Class,這就打破了只能向父classloader請(qǐng)求的限制了。這個(gè)機(jī)制可以滿足當(dāng)我們的classpath是在運(yùn)行時(shí)才確定,并由定制的 classloader加載的時(shí)候,由system classloader(即在jvm classpath中)加載的class可以通過(guò)context classloader獲得定制的classloader并加載入特定的class(通常是抽象類和接口,定制的classloader中是其實(shí)現(xiàn)),例如web應(yīng)用中的servlet就是用這種機(jī)制加載的.

            好了,現(xiàn)在我們了解了classloader的結(jié)構(gòu)和工作原理,那么我們?nèi)绾螌?shí)現(xiàn)在運(yùn)行時(shí)的動(dòng)態(tài)載入和更新呢?只要我們能夠動(dòng)態(tài)改變類搜索路徑和清除 classloader的cache中已經(jīng)載入的Class就行了,有兩個(gè)方案,一是我們繼承一個(gè)classloader,覆蓋loadclass方法,動(dòng)態(tài)的尋找Class文件并使用defineClass方法來(lái);另一個(gè)則非常簡(jiǎn)單實(shí)用,只要重新使用一個(gè)新的類搜索路徑來(lái)new一個(gè) classloader就行了,這樣即更新了類搜索路徑以便來(lái)載入新的Class,也重新生成了一個(gè)空白的cache(當(dāng)然,類搜索路徑不一定必須更改)。噢,太好了,我們幾乎不用做什么工作,java.netURLClassLoader正是一個(gè)符合我們要求的classloader!我們可以直接使用或者繼承它就可以了!

    這是j2se1.4 API的doc中URLClassLoader的兩個(gè)構(gòu)造器的描述:
    URLClassLoader(URL[] urls)
             Constructs a new URLClassLoader for the specified URLs using the default delegation parent ClassLoader.
    URLClassLoader(URL[] urls, ClassLoader parent)
             Constructs a new URLClassLoader for the given URLs.
    其中URL[] urls就是我們要設(shè)置的類搜索路徑,parent就是這個(gè)classloader的parent classloader,默認(rèn)的是system classloader。


            好,現(xiàn)在我們能夠動(dòng)態(tài)的載入Class了,這樣我們就可以利用newInstance方法來(lái)獲得一個(gè)Object。但我們?nèi)绾螌⒋薕bject造型呢?可以將此Object造型成它本身的Class嗎?

            首先讓我們來(lái)分析一下java源文件的編譯,運(yùn)行吧!javac命令是調(diào)用“JAVA_HOME/lib/tools.jar”中的“com.sun.tools.javac.Main”的compile方法來(lái)編譯:

       public static int compile(String as[]);

       public static int compile(String as[], PrintWriter printwriter);

    返回0表示編譯成功,字符串?dāng)?shù)組as則是我們用javac命令編譯時(shí)的參數(shù),以空格劃分。例如:
    javac -classpath c:\foo\bar.jar;. -d c:\ c:\Some.java
    則字符串?dāng)?shù)組as為{"-classpath","c:\\foo\\bar.jar;.","-d","c:\\","c:\Some.java"},如果帶有PrintWriter參數(shù),則會(huì)把編譯信息出到這個(gè)指定的printWriter中。默認(rèn)的輸出是 System.err。

    其中 Main是由JVM使用Launcher初始化的system classloader載入的,根據(jù)全盤(pán)負(fù)責(zé)原則,編譯器在解析這個(gè)java源文件時(shí)所發(fā)現(xiàn)的它所依賴和引用的所有Class也將由system classloader載入,如果system classloader不能載入某個(gè)Class時(shí),編譯器將拋出一個(gè)“cannot resolve symbol”錯(cuò)誤。

    所以首先編譯就通不過(guò),也就是編譯器無(wú)法編譯一個(gè)引用了不在CLASSPATH中的未知Class的java源文件,而由于拼寫(xiě)錯(cuò)誤或者沒(méi)有把所需類庫(kù)放到CLASSPATH中,大家一定經(jīng)常看到這個(gè)“cannot resolve symbol”這個(gè)編譯錯(cuò)誤吧!

    其次,就是我們把這個(gè)Class放到編譯路徑中,成功的進(jìn)行了編譯,然后在運(yùn)行的時(shí)候不把它放入到CLASSPATH中而利用我們自己的 classloader來(lái)動(dòng)態(tài)載入這個(gè)Class,這時(shí)候也會(huì)出現(xiàn)“java.lang.NoClassDefFoundError”的違例,為什么呢?

    我們?cè)賮?lái)分析一下,首先調(diào)用這個(gè)造型語(yǔ)句的可執(zhí)行的Class一定是由JVM使用Launcher初始化的system classloader載入的,根據(jù)全盤(pán)負(fù)責(zé)原則,當(dāng)我們進(jìn)行造型的時(shí)候,JVM也會(huì)使用system classloader來(lái)嘗試載入這個(gè)Class來(lái)對(duì)實(shí)例進(jìn)行造型,自然在system classloader尋找不到這個(gè)Class時(shí)就會(huì)拋出“java.lang.NoClassDefFoundError”的違例。

    OK,現(xiàn)在讓我們來(lái)總結(jié)一下,java文件的編譯和Class的載入執(zhí)行,都是使用Launcher初始化的system classloader作為類載入器的,我們無(wú)法動(dòng)態(tài)的改變system classloader,更無(wú)法讓JVM使用我們自己的classloader來(lái)替換system classloader,根據(jù)全盤(pán)負(fù)責(zé)原則,就限制了編譯和運(yùn)行時(shí),我們無(wú)法直接顯式的使用一個(gè)system classloader尋找不到的Class,即我們只能使用Java核心類庫(kù),擴(kuò)展類庫(kù)和CLASSPATH中的類庫(kù)中的Class。

    還不死心!再嘗試一下這種情況,我們把這個(gè)Class也放入到CLASSPATH中,讓system classloader能夠識(shí)別和載入。然后我們通過(guò)自己的classloader來(lái)從指定的class文件中載入這個(gè)Class(不能夠委托 parent載入,因?yàn)檫@樣會(huì)被system classloader從CLASSPATH中將其載入),然后實(shí)例化一個(gè)Object,并造型成這個(gè)Class,這樣JVM也識(shí)別這個(gè)Class(因?yàn)?system classloader能夠定位和載入這個(gè)Class從CLASSPATH中),載入的也不是CLASSPATH中的這個(gè)Class,而是從 CLASSPATH外動(dòng)態(tài)載入的,這樣總行了吧!十分不幸的是,這時(shí)會(huì)出現(xiàn)“java.lang.ClassCastException”違例。

    為什么呢?我們也來(lái)分析一下,不錯(cuò),我們雖然從CLASSPATH外使用我們自己的classloader動(dòng)態(tài)載入了這個(gè)Class,但將它的實(shí)例造型的時(shí)候是JVM會(huì)使用system classloader來(lái)再次載入這個(gè)Class,并嘗試將使用我們的自己的classloader載入的Class的一個(gè)實(shí)例造型為system classloader載入的這個(gè)Class(另外的一個(gè))。大家發(fā)現(xiàn)什么問(wèn)題了嗎?也就是我們嘗試將從一個(gè)classloader載入的Class的一個(gè)實(shí)例造型為另外一個(gè)classloader載入的Class,雖然這兩個(gè)Class的名字一樣,甚至是從同一個(gè)class文件中載入。但不幸的是JVM 卻認(rèn)為這個(gè)兩個(gè)Class是不同的,即JVM認(rèn)為不同的classloader載入的相同的名字的Class(即使是從同一個(gè)class文件中載入的)是不同的!這樣做的原因我想大概也是主要出于安全性考慮,這樣就保證所有的核心Java類都是system classloader載入的,我們無(wú)法用自己的classloader載入的相同名字的Class的實(shí)例來(lái)替換它們的實(shí)例。

    看到這里,聰明的讀者一定想到了該如何動(dòng)態(tài)載入我們的Class,實(shí)例化,造型并調(diào)用了吧!

    那就是利用面向?qū)ο蟮幕咎匦灾坏亩嘈涡浴N覀儼盐覀儎?dòng)態(tài)載入的Class的實(shí)例造型成它的一個(gè)system classloader所能識(shí)別的父類就行了!這是為什么呢?我們還是要再來(lái)分析一次。當(dāng)我們用我們自己的classloader來(lái)動(dòng)態(tài)載入這我們只要把這個(gè)Class的時(shí)候,發(fā)現(xiàn)它有一個(gè)父類Class,在載入它之前JVM先會(huì)載入這個(gè)父類Class,這個(gè)父類Class是system classloader所能識(shí)別的,根據(jù)委托機(jī)制,它將由system classloader載入,然后我們的classloader再載入這個(gè)Class,創(chuàng)建一個(gè)實(shí)例,造型為這個(gè)父類Class,注意了,造型成這個(gè)父類 Class的時(shí)候(也就是上溯)是面向?qū)ο蟮膉ava語(yǔ)言所允許的并且JVM也支持的,JVM就使用system classloader再次載入這個(gè)父類Class,然后將此實(shí)例造型為這個(gè)父類Class。大家可以從這個(gè)過(guò)程發(fā)現(xiàn)這個(gè)父類Class都是由 system classloader載入的,也就是同一個(gè)class loader載入的同一個(gè)Class,所以造型的時(shí)候不會(huì)出現(xiàn)任何異常。而根據(jù)多形性,調(diào)用這個(gè)父類的方法時(shí),真正執(zhí)行的是這個(gè)Class(非父類 Class)的覆蓋了父類方法的方法。這些方法中也可以引用system classloader不能識(shí)別的Class,因?yàn)楦鶕?jù)全盤(pán)負(fù)責(zé)原則,只要載入這個(gè)Class的classloader即我們自己定義的 classloader能夠定位和載入這些Class就行了。

    這樣我們就可以事先定義好一組接口或者基類并放入CLASSPATH中,然后在執(zhí)行的時(shí)候動(dòng)態(tài)的載入實(shí)現(xiàn)或者繼承了這些接口或基類的子類。還不明白嗎?讓我們來(lái)想一想Servlet吧,web application server能夠載入任何繼承了Servlet的Class并正確的執(zhí)行它們,不管它實(shí)際的Class是什么,就是都把它們實(shí)例化成為一個(gè)Servlet Class,然后執(zhí)行Servlet的init,doPost,doGet和destroy等方法的,而不管這個(gè)Servlet是從web- inf/lib和web-inf/classes下由system classloader的子classloader(即定制的classloader)動(dòng)態(tài)載入。說(shuō)了這么多希望大家都明白了。在applet,ejb等容器中,都是采用了這種機(jī)制.

    對(duì)于以上各種情況,希望大家實(shí)際編寫(xiě)一些example來(lái)實(shí)驗(yàn)一下。

    最后我再說(shuō)點(diǎn)別的, classloader雖然稱為類加載器,但并不意味著只能用來(lái)加載Class,我們還可以利用它也獲得圖片,音頻文件等資源的URL,當(dāng)然,這些資源必須在CLASSPATH中的jar類庫(kù)中或目錄下。我們來(lái)看API的doc中關(guān)于ClassLoader的兩個(gè)尋找資源和Class的方法描述吧:
            public URL getResource(String name)
            用指定的名字來(lái)查找資源,一個(gè)資源是一些能夠被class代碼訪問(wèn)的在某種程度上依賴于代碼位置的數(shù)據(jù)(圖片,音頻,文本等等)。
                   一個(gè)資源的名字是以'/'號(hào)分隔確定資源的路徑名的。
                   這個(gè)方法將先請(qǐng)求parent classloader搜索資源,如果沒(méi)有parent,則會(huì)在內(nèi)置在虛擬機(jī)中的classloader(即bootstrap classloader)的路徑中搜索。如果失敗,這個(gè)方法將調(diào)用findResource(String)來(lái)尋找資源。
            public static URL getSystemResource(String name)
                   從用來(lái)載入類的搜索路徑中查找一個(gè)指定名字的資源。這個(gè)方法使用system class loader來(lái)定位資源。即相當(dāng)于ClassLoader.getSystemClassLoader().getResource(name)。

    例如:
       System.out.println(ClassLoader.getSystemResource("java/lang/String.class"));
    的結(jié)果為:
       jar:文件:/C:/j2sdk1.4.1_01/jre/lib/rt.jar!/java/lang/String.class
    表明String.class文件在rt.jar的java/lang目錄中。
    因此我們可以將圖片等資源隨同Class一同打包到j(luò)ar類庫(kù)中(當(dāng)然,也可單獨(dú)打包這些資源)并添加它們到class loader的搜索路徑中,我們就可以無(wú)需關(guān)心這些資源的具體位置,讓class loader來(lái)幫我們尋找了!

    posted @ 2007-12-07 15:23 心。 閱讀(1551) | 評(píng)論 (0)編輯 收藏
    主站蜘蛛池模板: 免费二级毛片免费完整视频| 在线观看免费为成年视频| 久草视频在线免费| 99热在线精品免费全部my| 国产传媒在线观看视频免费观看| va亚洲va日韩不卡在线观看| 亚洲无线码在线一区观看| 精品亚洲麻豆1区2区3区| 亚洲日韩国产欧美一区二区三区 | 97精品免费视频| 亚洲免费网站观看视频| 四虎影视免费永久在线观看| 亚洲无人区一区二区三区| 亚洲视频欧洲视频| 看亚洲a级一级毛片| 国产一级片免费看| 成年在线观看网站免费| jlzzjlzz亚洲乱熟在线播放| 91嫩草私人成人亚洲影院| 久久亚洲中文无码咪咪爱| 东方aⅴ免费观看久久av| 免费观看成人毛片a片2008| 亚洲A丁香五香天堂网| 亚洲天堂视频在线观看| 久久无码av亚洲精品色午夜| 四虎国产精品免费永久在线| 2020久久精品国产免费| 亚洲中文字幕成人在线| 亚洲伊人久久大香线蕉在观 | 亚洲国产精品综合久久20| 人禽伦免费交视频播放| www.免费在线观看| 亚洲毛片不卡av在线播放一区| 久久综合亚洲色HEZYO社区| 美女黄网站人色视频免费| 999久久久免费精品播放| 亚洲成A人片在线观看无码3D| 亚洲电影免费观看| 国产黄在线播放免费观看| 69成人免费视频无码专区| 亚洲精品无码久久久久去q|