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

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

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

    posts - 78, comments - 34, trackbacks - 0, articles - 1
      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

                    從張老師的基礎(chǔ)增強(qiáng)課上,我就想深入了解一下類加載器。然后聽(tīng)懂了張老師的課,知道了JAVA類加載的方式,以及實(shí)現(xiàn)自己的類加載器的應(yīng)用。但一直沒(méi)有自己去編寫(xiě)類加載器,也對(duì)class文件的具體處理方式不了解。今日休息,有時(shí)間深入了解一下。

     

    一、JAVA有三個(gè)類加載器:

    1.bootstrap class loader,負(fù)責(zé)加載系統(tǒng)類,比如jdkrt.jar包里的類。

    2.extension class loader,負(fù)責(zé)加載jre/lib/ext目錄下的所有類。

    3.system class loader,負(fù)責(zé)加載環(huán)境變量classpath指向目錄下的所有類。

     

    他們?nèi)齻€(gè)依次是“父子關(guān)系”,因?yàn)?/span>bootstrap class loader一般是使用C語(yǔ)言編寫(xiě)的,所以用戶無(wú)法獲取它的對(duì)象。

     

    當(dāng)在classpath環(huán)境變量中的一個(gè)class文件被加載時(shí),system class loader會(huì)將class交給父類extension class loader加載,extension class loader會(huì)將class交給bootstrap class loader加載。如果bootstrap class loader加載不了,則返回給extension class loader加載,如果extension class loader加載不了,則返回給system class loader加載。

     

    被其中一個(gè)加載器成功加載后,便解析class文件。如果class文件中有使用到其他類對(duì)象,則繼續(xù)調(diào)用類加載器加載。

     

    有些情況下不希望被用戶看到Class文件的明文,比如為了保護(hù)軟件的安全、防止破解等。《JAVA核心技術(shù)第2卷》也有提到編寫(xiě)自己的類加載器,實(shí)現(xiàn)加載被加了密的class文件。

     

    下面實(shí)現(xiàn)一個(gè)自己的類加載器,加載被加密了的class文件:

     

    EasyTest.java用于被自定義類加載器加載。

    public class EasyTest {

          public void print(){

                System.out.println("EasyTest,you did it!");

          }

    }

     

    Mycipher.java用于加密EasyTest.class

    package cn.itcast.cc.cipher;

     

    import java.io.*;

    import java.security.Key;

    import javax.crypto.*;

     

    public class MyCipher {

          private Key key = null;

          private String traninfo = null;

     

          public MyCipher(Key key, String traninfo) {

                this.key = key;

                this.traninfo = traninfo;

          }

     

          public void cipher(InputStream ins, OutputStream ous) throws IOException {

                // 創(chuàng)建加密輸出流

                Cipher cip = null;

                CipherOutputStream cos = null;

                try {

                      cip = Cipher.getInstance(this.traninfo);

                      cip.init(Cipher.ENCRYPT_MODE, this.key);

                      cos = new CipherOutputStream(ous, cip);

                      // 寫(xiě)出到輸入流

                      int len = 0;

                      byte[] buf = new byte[1024];

                      while ((len = ins.read(buf)) != -1) {

                            cos.write(buf, 0, len);

                      }

                } catch (Exception e) {

                      e.printStackTrace();

                } finally {

                      // 釋放輸入和輸出流

                      cos.close();

                      ins.close();

                      ous.close();

                }

          }

    }

     

    MyClassLoader.java是自定義類加載器,用于解密被加密后的class文件。

    package cn.itcast.cc.classloader;

     

    import java.io.*;

    import java.security.Key;

    import javax.crypto.*;

     

    public class MyClassLoader extends ClassLoader {

          private Key key = null;

          private String traninfo = null;

     

          public MyClassLoader(Key key, String traninfo) {

                this.key = key;

                this.traninfo = traninfo;

          }

     

          @Override

          @SuppressWarnings("unchecked")

          protected Class findClass(String name) throws ClassNotFoundException {

                // 獲取class解密后的字節(jié)碼

                byte[] classBytes = null;

                try {

                      classBytes = loadClassBytes(name);

                } catch (Exception e) {

                      throw new ClassNotFoundException(name);

                }

               

                // 使用字節(jié)碼,實(shí)例類對(duì)象

                String clname = name.substring(name.lastIndexOf("/") + 1, name

                            .lastIndexOf("."));

                Class cl = defineClass(clname, classBytes, 0, classBytes.length);

                if (cl == null)

                      throw new ClassNotFoundException(name);

                return cl;

          }

     

          private byte[] loadClassBytes(String name) throws IOException {

                // 讀入文件

                FileInputStream ins = null;

                ByteArrayOutputStream baos = null;

                CipherInputStream cis = null;

                byte[] result = null;

                try {

                      ins = new FileInputStream(name);

                      Cipher cip = Cipher.getInstance(this.traninfo);

                      cip.init(Cipher.DECRYPT_MODE, this.key);

                      // 使用密碼解密class文件

                      cis = new CipherInputStream(ins, cip);

                      baos = new ByteArrayOutputStream();

                      int len = 0;

                      byte[] buf = new byte[1024];

                      while ((len = cis.read(buf)) != -1) {

                            baos.write(buf, 0, len);

                      }

                      result = baos.toByteArray();

                } catch (Exception e) {

                      e.printStackTrace();

                } finally {

                      // 釋放流

                      baos.close();

                      cis.close();

                      ins.close();

                }

     

                return result;

          }

    }

     

    Test.java,用于測(cè)試自定義類加載器。

    package cn.itcast.cc.testcalss;

     

    import java.io.*;

    import java.lang.reflect.Method;

    import java.security.Key;

    import javax.crypto.KeyGenerator;

    import cn.itcast.cc.cipher.MyCipher;

    import cn.itcast.cc.classloader.MyClassLoader;

     

    public class Test {

          public static void main(String[] args) {

                KeyGenerator keyGen;

                try {

                      // 創(chuàng)建密鑰

                      keyGen = KeyGenerator.getInstance("AES");

                      keyGen.init(128);

                      Key key = keyGen.generateKey();

                      keyGen = null;

     

                      MyCipher mc = new MyCipher(key,"AES/ECB/PKCS5Padding");

                      mc.cipher(new FileInputStream(new File("C:/EasyTestbak.class")),

                                  new FileOutputStream(new File("C:/EasyTest.class")));

     

                      MyClassLoader mcl = new MyClassLoader(key,"AES/ECB/PKCS5Padding");

                     

                      Class clazz = mcl.loadClass("C:/EasyTest.class");

                      Method meth = clazz.getMethod("print", null);

                      meth.invoke(clazz.newInstance(), null);

     

                } catch (Exception e1) {

                      e1.printStackTrace();

                }

          }

    }

     

    注意:將EasyTest.java編譯后放到C盤:C:/EasyTestbak.class

     

    例子寫(xiě)的不干凈,主要是為了演示自定義類加載器!

     

                學(xué)習(xí)了tomcat servlet以來(lái)便對(duì)它們的實(shí)現(xiàn)機(jī)制比較感興趣,雖然已經(jīng)弄懂了他們簡(jiǎn)單的實(shí)現(xiàn)原理。但今日看到《實(shí)現(xiàn)自己的類加載器》這篇文章時(shí),讓對(duì)有了更深入的了解。在tomcatwebapps目錄下的所有WEB應(yīng)用中的class文件和jar文件,都是在Tomcat啟動(dòng)時(shí)將全路徑記錄到URLClassloader中。需要什么類,直接調(diào)用URLClassloader.loaderclass()方法即可!

     

                我原本想自己找到class文件的全路徑,然后調(diào)用class.forname的方法不也可以嗎?但如果有JAR包,我還需要使用JARInputstream讀入,然后再搜索嗎?這樣太麻煩,所以還是使用URLClassloader比較好,它全處理了。

     

                它的實(shí)現(xiàn)原理,請(qǐng)看《實(shí)現(xiàn)自己的類加載器》 http://ajava.org/course/java/14990.html

     

     

    參考文獻(xiàn):《實(shí)現(xiàn)自己的類加載器》 http://ajava.org/course/java/14990.html


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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 风间由美在线亚洲一区| 亚洲最大av无码网址| 亚洲日韩精品A∨片无码| 亚洲色在线无码国产精品不卡| 久久中文字幕免费视频| 狠狠色伊人亚洲综合成人| 岛国岛国免费V片在线观看| 亚洲熟妇少妇任你躁在线观看无码 | 亚洲avav天堂av在线不卡 | 亚洲精品视频免费观看| 日韩大片免费观看视频播放| 免费一级毛片清高播放| 精品亚洲国产成人av| 亚洲人成无码久久电影网站| 一级免费黄色大片| 亚洲精品无码永久中文字幕| a毛片免费全部在线播放** | 图图资源网亚洲综合网站| 国产精品免费AV片在线观看| 91情国产l精品国产亚洲区| 亚欧色视频在线观看免费| 亚洲av无码电影网| 国产一区二区三区在线免费观看| 毛片亚洲AV无码精品国产午夜| 亚洲国产a级视频| 九九美女网站免费| 亚洲中文字幕AV在天堂| 日韩免费电影在线观看| 久久精品成人免费观看97| 亚洲一本综合久久| 香蕉高清免费永久在线视频| 日韩在线观看视频免费| 亚洲av午夜福利精品一区| 三年片在线观看免费大全 | a级毛片在线免费看| 亚洲成人网在线播放| 国产精品免费视频播放器| 亚洲冬月枫中文字幕在线看| 视频一区在线免费观看| 亚洲AV成人片无码网站| 国产中文字幕免费|