10、カスタムクラスローダ

カスタムクラスローダ3つの段階:

  1、継承クラスローダ。

  2、にfindClass()メソッドを書き換えます。

  図3にfindClassにおいて()defineClassメソッド()メソッドを呼び出します。

パッケージcom.shtec.classLoader; 

インポートjava.io.ByteArrayOutputStreamを、
 インポートのjava.io.File;
 インポートjava.io.FileInputStream;
 インポートにjava.io.IOException;
 インポートするjava.io.InputStream; 

/ ** 
 *カスタムクラスローディングステップ3の:
 * 1、クラスローダ継承
 * 2、にfindClass()メソッド書き換え
 にfindClass呼び出しdefineClass()メソッド()メソッドで* 3、
 *   
 * @author sunhao 
 * 
 * / 
パブリック クラス CustomClassLoader 延びているクラスローダ{ 
    
    プライベート文字列をclassLoaderName ;
     プライベート文字列のclassPath; //クラスローダパスロード
    プライベート 静的 最終列=接尾辞「.classファイルを」; 
    
    公共CustomClassLoader(){} 
    
    公共CustomClassLoader(文字列classLoaderName){
         スーパー(); // 親クラスローダローダなどのシステムクラスローダ
        この .classLoaderName = classLoaderName; 
    } 
    
    公共CustomClassLoader(クラスローダの親、ストリングclassLoaderName){
         スーパー(親); // 表示ローダ親クラスローダ
        この .classLoaderName = classLoaderName; 
    } 

    公共 ボイドsetClassPath(文字列のclassPath){
         この= .classpath クラスパスを; 
    } 

    / * 
     * ***************************************** *********************************************************** 
     *はloadClass(文字列名、ブール決意)メソッドのクラスローダは、*メソッドにfindClassを呼び出し、
     この*カスタムクラスローダを示す実行する方法は、有効にする* 
     * ************************************** ********************************* 
     * / 
    @Overrideは、
    保護されたクラスを<?>にfindClass(文字列名)がスローClassNotFoundExceptionが{ 
        
        System.out.println( "[カスタムクラスローダ" + この .classLoaderName + "]クラスを探す" + 名前); 
        
        バイト []データ= この.loadClassData(名);
        
        // クラスオブジェクトへのバイト配列はdefineClassメソッド
        戻り 、この .defineClass(名前、データ、0 、data.length); 
    } 
    
    / * 
     *の.classファイルがロードされ、バイト配列に変換する
     * / 
    プライベート バイト[] loadClassDataメソッド(文字クラス名){ 
        に入力ストリーム = NULL ;
         バイト []データ= NULL ; 
        ByteArrayOutputStream BAOS = NULL ; 
        クラス名 = className.replace( ""、 "/" );
         試み{  = 新しい新規のFileInputStream(新しい新規ファイル(この .classPath +クラス名+ サフィックス)); 
            たBAO = 新しいByteArrayOutputStream();
            バイト []バッファ= 新しい バイト [8192 ];
            int型のlen = 0 ;
            一方、(!(LEN = in.read(バッファ))= -1 ){ 
                baos.write(バッファ、 0 、LEN)。
            } 
            データ = baos.toByteArray()。
        } キャッチ(例外e){ 
            e.printStackTrace(); 
        } 最後に{
             場合(中!=NULL ){
                 試み{ 
                    in.close()。
                } キャッチ(IOExceptionを電子){ 
                    e.printStackTrace(); 
                } 
            } 
            もし(BAOを!= NULL ){
                 試み{ 
                    baos.close()。
                } キャッチ(IOExceptionを電子){ 
                    e.printStackTrace(); 
                } 
            } 
        } 
        戻り値のデータ、
    } 
    
    パブリック 静的 ボイドメイン(文字列[]引数)スロー例外{ 
        
        CustomClassLoader customClassLoader = 新しい CustomClassLoader( "customClassLoaderを" )。
        customClassLoader.setClassPath( "D:\\クラス\\" ); 
        
        クラス <?> clazz = customClassLoader.loadClass( "com.shtec.classLoader.Test" ); 
        System.out.println( "当前类加载器:" + clazz.getClassLoader());
     

// 1、デフォルトでは、書き換え「にfindClass()」メソッドが実行されていない、クラスはカスタム有効なりませクラスローダがロードの操作
//出力を:
//現在のクラスローダ:sun.misc。 $ @ 73d16e93 AppClassLoaderランチャー
/ *
*理由:Javaのクラスローダがロードクラス、親は、「com.shtec.classLoader.Test」カテゴリ負荷にカスタムクラスローダによって、ある[委任]メカニズムに従います
*カスタムクラスローダがデフォルトの親クラスローダがロードするために最初の親ローダによってそれに割り当てられたタスク、およびカスタムクラスローダをロードします[システム](表示コンストラクタ定義されたクラスローダから)、
*最後に、システムクラスローダーは、対応する.classファイルのテストクラスクラスパス(System.getProperties(「のjava.class.pathを」))が見つかり、それをロードします。
書き換え*だから、「にfindClass()」メソッドが出て、最終的な印刷を実行しません:[クラスローダ:sun.misc.Launcher$AppClassLoader@73d16e93]。
* /

/ *
* 2あなたは「にfindClass()」メソッド、原因を削除した後、クラスパスにTest.classファイルのみ、削除する必要があるの実装を書き換えたい場合は、システムクラスローダはの.classファイルをロードすることはできません、 「com.shtec.classLoader.Test.class」作業負荷に当社独自のクラスローダと呼ぶことにします。
*最終的な出力:
*カスタムクラスローダ] [customClassLoaderの検索クラスcom.shtec.classLoader.Test
*現在のクラスローダ:com.shtec.classLoader.CustomClassLoader@15db9742
* /

    } 
}

おすすめ

転載: www.cnblogs.com/sunhao1234/p/12343967.html