ClassLoaderがclassをロードするプロセス
4875 ワード
longdick http://longdick.iteye.comに転載
JAvaアプリケーション環境の異なるclassは、それぞれ異なるClassLoaderによってロードされます.1つのjvmのデフォルトのclassloaderには、Bootstrap ClassLoader、Extension ClassLoader、App ClassLoaderがあり、それぞれの役割を果たしています.
Bootstrap ClassLoaderはjavaベースクラスのロードを担当し、主に%JRE_HOME/lib/ディレクトリの下のrt.jar、resources.jar、charsets.JArやclassなど Extension ClassLoaderはjava拡張クラスのロードを担当し、主に%JRE_HOME/lib/extディレクトリのjarとclass App ClassLoaderは、現在のjavaアプリケーションのclasspathのすべてのクラスをロードします.
Bootstrap ClassLoaderはJVMレベルで、C++によって書かれています.Extension ClassLoader、App ClassLoaderはjavaクラスであり、URLClassLoaderスーパークラスから継承されています.Bootstrap ClassLoaderはJVMによって起動し、sunを初期化する.misc.Launcher ,sun.misc.Launcher Extension ClassLoader、App ClassLoaderを初期化します.
次の図はClassLoaderのロードクラスフローチャートで、クラスをロードするプロセスクラスの例としてClassLoader全体のプロセスを示します.
Bootstrap ClassLoader、Extension ClassLoader、App ClassLoaderの3つの関係は以下の通りです.
Bootstrap ClassLoaderはExtension ClassLoaderのparent、Extension ClassLoaderはApp ClassLoaderのparentです.
しかし、これは継承関係ではなく、意味的な定義であり、基本的には、ClassLoaderの実装ごとにParent ClassLoaderがあります.
現在のClassLoaderのparentは、ClassLoaderのgetParentメソッドで取得できます.Bootstrap ClassLoaderはjava classではないのでExtension ClassLoaderのgetParentメソッドはNULLを返します.
ClassLoaderの原理と流れを理解したら、ClassLoaderをカスタマイズしてみましょう.
カスタムClassLoaderについて:
特殊なニーズのため、ClassLoaderのロード動作をカスタマイズする必要がある場合があります.この場合、ClassLoaderをカスタマイズする必要があります.
カスタムClassLoaderはClassLoader抽象クラスを継承し、findClassメソッドを書き換える必要があります.このメソッドはClassLoaderがclassを検索する方法を定義します.
主に拡張できる方法は次のとおりです.
findClassはClassを検索する方法を定義します
defineClassクラスファイルバイトコードをjvmのclassにロード
findResourceは、リソースの検索方法を定義します.
面倒であれば、既存のClassLoader実装を直接使用したり継承したりすることができます.例えば、
Extension ClassLoaderとApp ClassLoaderはjavaです.net.URLClassLoaderのサブクラス.
これはURLClassLoaderの構造方法です.
public URLClassLoader(URL[] urls, ClassLoader parent)
public URLClassLoader(URL[] urls)
urlsパラメータは、ロードする必要があるClassPath url配列で、parent ClassLoaderを指定できます.指定しない場合、デフォルトは現在の呼び出しクラスのClassLoaderをparentとします.
コードの例:
Javaコード
ClassLoader classLoader = new URLClassLoader(urls); Thread.currentThread().setContextClassLoader(classLoader); Class clazz=classLoader.loadClass("com.company.MyClass");//loadClassメソッドを使用してclassをロードします.このclassはurlsパラメータで指定されたclasspathの下にあります. Method taskMethod = clazz.getMethod("doTask", String.class, String.class);//反射で何かできるようになりました taskMethod.invoke(clazz.newInstance(),"hello","world");
classloaderはクラスをロードするためにすべての責任を負うメカニズムを使用します.全責任とは、1つのclassloaderが1つのClassをロードするとき、このClassが依存し参照するすべてのClassも、他のclassloaderを明示的に使用してロードしない限り、このclassloaderがロードを担当することである.
したがって、カスタムclassloaderのロードに成功しましたcom.company.MyClass以降、MyClassに依存するすべてのclassはこのclassLoaderによってロードされます.
カスタムClassLoaderは、特定のアプリケーションシーンで適用されます.特にclassを柔軟に動的にロードする必要がある場合です.
次の記事では、ClassLoaderをカスタマイズするアプリケーションのシーンを示します.興味のある方は、以下を参照してください.
http://longdick.iteye.com/blog/332580
JAvaアプリケーション環境の異なるclassは、それぞれ異なるClassLoaderによってロードされます.1つのjvmのデフォルトのclassloaderには、Bootstrap ClassLoader、Extension ClassLoader、App ClassLoaderがあり、それぞれの役割を果たしています.
Bootstrap ClassLoaderはJVMレベルで、C++によって書かれています.Extension ClassLoader、App ClassLoaderはjavaクラスであり、URLClassLoaderスーパークラスから継承されています.Bootstrap ClassLoaderはJVMによって起動し、sunを初期化する.misc.Launcher ,sun.misc.Launcher Extension ClassLoader、App ClassLoaderを初期化します.
次の図はClassLoaderのロードクラスフローチャートで、クラスをロードするプロセスクラスの例としてClassLoader全体のプロセスを示します.
Bootstrap ClassLoader、Extension ClassLoader、App ClassLoaderの3つの関係は以下の通りです.
Bootstrap ClassLoaderはExtension ClassLoaderのparent、Extension ClassLoaderはApp ClassLoaderのparentです.
しかし、これは継承関係ではなく、意味的な定義であり、基本的には、ClassLoaderの実装ごとにParent ClassLoaderがあります.
現在のClassLoaderのparentは、ClassLoaderのgetParentメソッドで取得できます.Bootstrap ClassLoaderはjava classではないのでExtension ClassLoaderのgetParentメソッドはNULLを返します.
ClassLoaderの原理と流れを理解したら、ClassLoaderをカスタマイズしてみましょう.
カスタムClassLoaderについて:
特殊なニーズのため、ClassLoaderのロード動作をカスタマイズする必要がある場合があります.この場合、ClassLoaderをカスタマイズする必要があります.
カスタムClassLoaderはClassLoader抽象クラスを継承し、findClassメソッドを書き換える必要があります.このメソッドはClassLoaderがclassを検索する方法を定義します.
主に拡張できる方法は次のとおりです.
findClassはClassを検索する方法を定義します
defineClassクラスファイルバイトコードをjvmのclassにロード
findResourceは、リソースの検索方法を定義します.
面倒であれば、既存のClassLoader実装を直接使用したり継承したりすることができます.例えば、
java.net.URLClassLoader
java.security.SecureClassLoader
java.rmi.server.RMIClassLoader
sun.applet.AppletClassLoader
Extension ClassLoaderとApp ClassLoaderはjavaです.net.URLClassLoaderのサブクラス.
これはURLClassLoaderの構造方法です.
public URLClassLoader(URL[] urls, ClassLoader parent)
public URLClassLoader(URL[] urls)
urlsパラメータは、ロードする必要があるClassPath url配列で、parent ClassLoaderを指定できます.指定しない場合、デフォルトは現在の呼び出しクラスのClassLoaderをparentとします.
コードの例:
Javaコード
ClassLoader classLoader = new URLClassLoader(urls);
Thread.currentThread().setContextClassLoader(classLoader);
Class clazz=classLoader.loadClass("com.company.MyClass");// loadClass class, class urls classpath 。
Method taskMethod = clazz.getMethod("doTask", String.class, String.class);//
taskMethod.invoke(clazz.newInstance(),"hello","world");
classloaderはクラスをロードするためにすべての責任を負うメカニズムを使用します.全責任とは、1つのclassloaderが1つのClassをロードするとき、このClassが依存し参照するすべてのClassも、他のclassloaderを明示的に使用してロードしない限り、このclassloaderがロードを担当することである.
したがって、カスタムclassloaderのロードに成功しましたcom.company.MyClass以降、MyClassに依存するすべてのclassはこのclassLoaderによってロードされます.
カスタムClassLoaderは、特定のアプリケーションシーンで適用されます.特にclassを柔軟に動的にロードする必要がある場合です.
次の記事では、ClassLoaderをカスタマイズするアプリケーションのシーンを示します.興味のある方は、以下を参照してください.
http://longdick.iteye.com/blog/332580