カスタムクラスローダ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
* /
}
}