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全体のプロセスを示します.
     
    ClassLoader加载class的流程 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 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