posts - 14,  comments - 37,  trackbacks - 0
                JavaClassLoaderPackage機制介紹了ClassLoader的委派機制,它是把裝載的任務傳遞給上級的裝載器的,依次類推,直到啟動類裝載器(沒有上級類裝載器)。如果啟動類裝載器能夠裝載這個類,那么它會首先裝載。如果不能,則往下傳遞。其實這引出一個運行時包的概念。不同裝載器裝載的類,即使包名相同也不能互相訪問。這樣保證了核心類庫不被破壞。(by juxtapose)

                本文將講述如何擴展ClassLoader類實現一個自己的類裝載器,每個Class對象都有一個引用指向裝載他的ClassLoader,你可以通過public ClassLoader getClassLoader()方法得到它。為了創建自己的類裝載器我們應該擴展ClassLoader類,這是一個抽象類。我們目的是從本地文件系統使用我們實現的類裝載器裝載一個類。我們創建一個FileClassLoader extends ClassLoader。我們需要覆蓋ClassLoader中的
          findClass(String name)
          方法,這個方法通過類的名字而得到一個Class對象。

          public Class findClass(String name)
          {
          byte[] data = loadClassData(name);
          return defineClass(name, data, 0, data.length);
          }

           

          我們還應該提供一個方法loadClassData(String name),通過類的名稱返回class文件的字節數組。然后使用ClassLoader提供的defineClass()方法我們就可以返回Class對象了。

          public byte[] loadClassData(String name)
          {
          FileInputStream fis 
          = null;
          byte[] data = null;
          try
          {
          fis 
          = new FileInputStream(new File(drive + name + fileType));
          ByteArrayOutputStream baos 
          = new ByteArrayOutputStream();
          int ch = 0;
          while ((ch = fis.read()) != -1)
          {
          baos.write(ch);

          }

          data 
          = baos.toByteArray();
          }
           catch (IOException e)
          {
          e.printStackTrace();
          }


          return data;
          }


          這里我們是從D盤裝載一個類。

          下面我們提供一個類public class MyApp{},類中沒有定義任何方法和變量,下面我們編譯MyApp.java得到MyApp.class,然后把文件放在D盤的根目錄。為了證明MyApp.class是被我們定義的classloader裝載的,我們在FileClassLoadermain()方法中打印出裝載MyApp.class的類裝載器的名稱。
           

          public static void main(String[] args) throws Exception
          {
          FileClassLoader loader 
          = new FileClassLoader();
          Class objClass 
          = loader.loadClass("MyApp"true);
          Object obj 
          = objClass.newInstance();
          System.out.println(objClass.getName());
          System.out.println(objClass.getClassLoader());


          }

          編譯FileClassLoader
          javac FileClassLoader.java
          然后運行java FileClassLoader 可以看到輸出結果為

          MyApp
          FileClassLoader@1a5ab41

          如果你把MyApp.class放入到你程序的所在目錄會出現什么情況呢?讀者自己實踐一下吧!

          結果為:MyApp

          sun.misc.Launcher$AppClassLoader@92e78c

          下面給出FileClassLoader的源代碼。/*

           

          * Created on 2005-7-27

          *

          * To change the template for this generated file go to

          * Window>Preferences>Java>Code Generation>Code and Comments

          */


          /**

          @author liuxiang

          *

          * To change the template for this generated type comment go to

          * Window>Preferences>Java>Code Generation>Code and Comments

          */


          import java.io.ByteArrayOutputStream;

          import java.io.File;

          import java.io.FileInputStream;

          import java.io.IOException;

          public class FileClassLoader extends ClassLoader

          {

          public static final String drive = "d:/";

          public static final String fileType = ".class";


          public FileClassLoader() {

          super();


          }



          public FileClassLoader(ClassLoader arg0) {

          super(arg0);

          }



          public Class findClass(String name)

          {

          byte[] data = loadClassData(name);

          /*

          * Converts an array of bytes into an instance of class Class. 

          * Before the Class can be used it must be resolved. 



          * This method assigns a default ProtectionDomain to the newly 

          * defined class. The ProtectionDomain contains the set of 

          * permissions granted when a call to Policy.getPolicy().getPermissions() 

          * is made with a code source of null,null. The default domain 

          * is created on the first invocation of defineClass, and re-used 

          * on subsequent calls. 

          * To assign a specific ProtectionDomain to the class, use the 

          * defineClass method that takes a ProtectionDomain as one of 

          * its arguments. 

          */


          /*

          * 該方法接受由原始字節組成的數組并把它轉化成class對象

          * 原始字節包含從文件系統或網絡裝入的data

          * defineClass管理JVM中許多復雜、神秘和依賴于實現的方面————

          * ————它把字節碼分析成運行時數據結構、校驗有效性等。

          */


          return defineClass(name, data, 0, data.length);

          }



          /*

          * 將對應的Class文件讀為byte[]

          */


          public byte[] loadClassData(String name)

          {

          FileInputStream fis 
          = null;

          byte[] data = null;

          try

          {

          //裝載d:根目錄下面的.class文件到data中

          fis 
          = new FileInputStream(new File(drive + name + fileType));

          ByteArrayOutputStream baos 
          = new ByteArrayOutputStream();

          int ch = 0;

          while ((ch = fis.read()) != -1)

          {

          baos.write(ch);


          }


          data 
          = baos.toByteArray();

          }
           catch (IOException e)

          {

          e.printStackTrace();

          }



          return data;

          }
           


          public static void main(String[] args) throws Exception

          {

          FileClassLoader loader 
          = new FileClassLoader();

          //裝載類MyApp

          Class objClass 
          = loader.loadClass("MyApp"true);

          //生成MyApp的一個實例

          Object obj 
          = objClass.newInstance();

          //獲得類的名稱

          System.out.println(objClass.getName());

          //獲得類的裝載器的名稱

          System.out.println(objClass.getClassLoader()); 

          }


          }

           

          posted on 2007-07-11 13:10 冰封的愛 閱讀(107) 評論(0)  編輯  收藏 所屬分類: J2EE
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          常用鏈接

          留言簿(3)

          隨筆檔案

          文章分類

          文章檔案

          相冊

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 宝山区| 阿瓦提县| 临颍县| 蒙自县| 广昌县| 二连浩特市| 凤阳县| 揭西县| 越西县| 凉山| 青田县| 资溪县| 凭祥市| 原阳县| 西平县| 耒阳市| 长沙县| 太仆寺旗| 武乡县| 延川县| 武宣县| 余姚市| 长治县| 昔阳县| 荔波县| 新余市| 景谷| 宿州市| 武功县| 青田县| 苍溪县| 海城市| 上林县| 通海县| 库车县| 嫩江县| 茌平县| 伊川县| 金溪县| 宁远县| 石城县|