自定義ClassLoader的實現

          Posted on 2007-04-06 12:25 久城 閱讀(4472) 評論(1)  編輯  收藏 所屬分類: JavaTest
          參考老師的例子,又在網上看了很多資料,總算自己敲出來一個。保存下先...

          自定義ClassLoader的實現:
          /**
           * classloader single
           * 
          @author zhaojiucheng
           * 
          @version 1.1
           *  新增兩個loadClass的重載方法
           *  在1.0的基礎上實現從指定jar包中加載指定的類文件
           
          */

          package zhao;

          import java.io.ByteArrayOutputStream;
          import java.io.File;
          import java.io.FileInputStream;
          import java.io.IOException;
          import java.io.InputStream;
          import java.util.ArrayList;
          import java.util.Enumeration;
          import java.util.Hashtable;
          import java.util.List;
          import java.util.jar.JarEntry;
          import java.util.jar.JarFile;
          import java.util.jar.JarInputStream;

          /**
           * 自定義類加載器
           
          */

          public class MyClassLoader extends ClassLoader {

              
          private static String MyClasspath = new String("");

              
          private static ArrayList loadClassList = new ArrayList();

              
          private static Hashtable loadClassHashTable = new Hashtable();

              
          public MyClassLoader() {

              }


              
          /**
               * 構造自定義的加載器 參數1:路徑名
               
          */

              
          public MyClassLoader(String MyClasspath) {
                  
          if (!MyClasspath.endsWith("\\")) {
                      MyClasspath 
          = MyClasspath + "\\";
                  }

                  
          this.MyClasspath = MyClasspath;
              }


              
          /**
               * 設置加載路徑 參數1:路徑名
               
          */

              
          public void SetMyClasspath(String MyClasspath) {
                  
          if (!MyClasspath.endsWith("\\")) {
                      MyClasspath 
          = MyClasspath + "\\";
                  }

                  
          this.MyClasspath = MyClasspath;
              }


              
          /**
               * 查找類并加載 參數1:文件名 被 loadClass() 調用
               
          */

              
          public Class findClass(String name) {
                  
          byte[] classData = null;
                  
          try {
                      classData 
          = loadClassData(name);
                  }
           catch (IOException e) {
                      e.printStackTrace();
                  }

                  Class c 
          = defineClass(name, classData, 0, classData.length);
                  loadClassHashTable.put(name, c);
                  System.out.println(
          "加載" + name + "類成功。");
                  
          return c;
              }


              
          /**
               * 讀取文件字節碼 參數1:文件名 被 findClass() 調用
               
          */

              
          private byte[] loadClassData(String name) throws IOException {
                  String filePath 
          = searchFile(MyClasspath, name + ".class");
                  System.out.println(filePath);
                  
          if (!(filePath == null || filePath == "")) {
                      FileInputStream inFile 
          = new FileInputStream(filePath);
                      
          byte[] classData = new byte[inFile.available()];
                      inFile.read(classData);
                      inFile.close();
                      
          return classData;
                  }

                  System.out.println(
          "讀取字節碼失敗。");
                  
          return null;
              }


              
          /**
               * 加載類 參數1:字節碼數組 參數2:類名
               
          */

              
          public Class loadClass(byte[] classData, String className)
                      
          throws ClassNotFoundException {
                  Class c 
          = defineClass(className, classData, 0, classData.length);
                  loadClassHashTable.put(className, c);
                  System.out.println(
          "加載" + className + "類成功。");
                  
          return c;
              }


              
          /**
               * 加載類 參數1:類名
               
          */

              
          public Class loadClass(String name) throws ClassNotFoundException {
                  
          return loadClass(name, false);
              }


              
          /**
               * 加載類 參數1:類名 參數2:是否分析這個類
               
          */

              
          protected Class loadClass(String name, boolean resolve)
                      
          throws ClassNotFoundException {
                  
          byte[] classData = null;
                  Class temp 
          = null;
                  
          // 如是系統類直接裝載并記錄后返回
                  if (name.startsWith("java.")) {
                      temp 
          = findSystemClass(name); // 調用父類方法
                      loadClassHashTable.put(name, temp);
                      System.out.println(
          "loadClass: SystemLoading " + name);
                      
          return temp;
                  }


                  
          try {
                      temp 
          = findLoadedClass(name);// here need try again it is how to
                      
          // work
                      if (temp != null{
                          System.out.println(name 
          + " have loaded");
                          
          return (temp);
                      }

                      
          try {
                          temp 
          = findClass(name);
                      }
           catch (Exception fnfe) {
                      }

                      
          if (temp == null{
                          temp 
          = findSystemClass(name);
                      }

                      
          if (resolve && (temp != null)) {
                          resolveClass(temp);
                      }

                      
          return temp;
                  }
           catch (Exception e) {
                      
          throw new ClassNotFoundException(e.toString());
                  }

              }


              
          /**
               * 加載類 參數1:要加載的類名 參數2:類所在的jar包名
               
          */

              
          protected Class loadClass(String className, String jarName)
                      
          throws ClassNotFoundException {
                  String jarPath 
          = searchFile(MyClasspath, jarName + ".jar");
                  JarInputStream in 
          = null;
                  
          if (!(jarPath == null || jarPath == "")) {
                      
          try {
                          in 
          = new JarInputStream(new FileInputStream(jarPath));
                          JarEntry entry;
                          
          while ((entry = in.getNextJarEntry()) != null{
                              
          // System.out.println(entry.getName());
                              String outFileName = entry.getName().substring(
                                      entry.getName().lastIndexOf(
          "/"+ 1,
                                      entry.getName().length());
                              
          // System.out.println(outFileName);
                              if (outFileName.equals(className + ".class")) {
                                  
          if (entry.getSize() == -1{
                                      System.out.println(
          "錯誤:無法讀取該文件!");
                                      
          return null;
                                  }

                                  
          byte[] classData = new byte[(int) entry.getSize()];
                                  in.read(classData);
                                  
          return loadClass(classData, className);
                              }

                          }

                      }
           catch (IOException e) {
                          e.printStackTrace();
                      }
           finally {
                          
          try {
                              in.close();
                          }
           catch (IOException e) {
                              e.printStackTrace();
                          }

                      }

                  }
           else {
                      System.out.println(
          "don't find the " + jarName + ".jar");
                      
          return null;
                  }

                  
          return null;
              }


              
          /**
               * 查詢文件 參數1:路徑名 參數2:文件名
               
          */

              
          public String searchFile(String classpath, String fileName) {
                  File f 
          = new File(classpath + fileName);
                  
          // 測試此路徑名表示的文件是否是一個標準文件
                  if (f.isFile()) {
                      
          return f.getPath();
                  }
           else {
                      
          // 返回由此抽象路徑名所表示的目錄中的文件和目錄的名稱所組成字符串數組
                      String objects[] = new File(classpath).list();
                      
          for (int i = 0; i < objects.length; i++{
                          
          // 測試此抽象路徑名表示的文件是否是一個目錄
                          if (new File(classpath + f.separator + objects[i])
                                  .isDirectory()) 
          {
                              
          // 迭代遍歷。separator是與系統有關的默認名稱分隔符
                              return searchFile(classpath + f.separator + objects[i]
                                      
          + f.separator, fileName);
                          }

                      }

                  }

                  System.out.println(
          "沒有找到文件:" + fileName);
                  
          return null;
              }
          ;

              
          public static void main(String[] args) {
                  MyClassLoader cl 
          = new MyClassLoader("e:\\test");
                  
          try {
                      
          // 從tools.jar包中加載ContentSigner類
                      cl.loadClass("ContentSigner""tools");
                  }
           catch (ClassNotFoundException e) {
                      e.printStackTrace();
                  }

              }

          }



          歡迎來訪!^.^!
          本BLOG僅用于個人學習交流!
          目的在于記錄個人成長.
          所有文字均屬于個人理解.
          如有錯誤,望多多指教!不勝感激!

          Feedback

          # re: 自定義ClassLoader的實現  回復  更多評論   

          2008-10-27 00:10 by zam
          很好,看了感覺很有收獲!

          Copyright © 久城

          主站蜘蛛池模板: 青冈县| 会理县| 孝感市| 吴旗县| 界首市| 南通市| 阳信县| 托克逊县| 滁州市| 偏关县| 通化市| 铜山县| 大洼县| 和田市| 远安县| 濉溪县| 玛曲县| 长垣县| 裕民县| 绥化市| 陵川县| 宜阳县| 合水县| 鄱阳县| 会理县| 丰镇市| 黎川县| 竹溪县| 昌乐县| 儋州市| 德阳市| SHOW| 克什克腾旗| 齐齐哈尔市| 伊川县| 石楼县| 漾濞| 株洲市| 垣曲县| 大渡口区| 新宾|