十一、JAVAマルチスレッドノート:スレッド上線文ローダ
2495 ワード
スレッドコンテキストクラスローダ(context class loader)はJDK 1.2から導入された.クラス#クラス#
前述したクラス・ローダのエージェント・モードでは、Javaアプリケーション開発で発生するクラス・ローダのすべての問題を解決することはできません.Javaは、サードパーティがこれらのインタフェースを実装できるようにするサービスプロバイダインタフェース(Service Provider Interface,SPI)を多く提供しています.一般的なSPIはJDBC、JCE、JNDI、JAXP、JBIなどがあります.これらのSPIのインタフェースはJavaコアライブラリによって提供され、例えばJAXPのSPIインタフェース定義は
スレッドコンテキストクラスローダはちょうどこの問題を解決した.何も設定しない場合、Javaアプリケーションのスレッドのコンテキストクラスローダはデフォルトでシステムコンテキストクラスローダです.SPIインタフェースのコードにスレッドコンテキストクラスローダを使用すると,SPI実装クラスへのロードに成功する.スレッドコンテキストクラスローダは、多くのSPIの実装で使用されます.
別のクラスをロードする方法を紹介します.
Class.forName
おすすめ記事:
https://blog.csdn.net/zhoudaxia/article/details/35897057
https://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html
java.lang.Thread
の方法 getContextClassLoader()
和 setContextClassLoader(ClassLoader cl)
スレッドを取得および設定するためのコンテキストクラスローダ.通らなかったら setContextClassLoader(ClassLoader cl)
メソッドを設定すると、スレッドは親スレッドのコンテキストクラスローダを継承します.Javaアプリケーションが実行する初期スレッドのコンテキストクラスローダは、システムクラスローダです.スレッドで実行されるコードは、このようなローダを使用してクラスとリソースをロードできます.前述したクラス・ローダのエージェント・モードでは、Javaアプリケーション開発で発生するクラス・ローダのすべての問題を解決することはできません.Javaは、サードパーティがこれらのインタフェースを実装できるようにするサービスプロバイダインタフェース(Service Provider Interface,SPI)を多く提供しています.一般的なSPIはJDBC、JCE、JNDI、JAXP、JBIなどがあります.これらのSPIのインタフェースはJavaコアライブラリによって提供され、例えばJAXPのSPIインタフェース定義は
javax.xml.parsers
バッグ中.これらのSPIの実装コードは、Javaアプリケーションに依存するjarパケットとして含まれる可能性が高い.JAXP SPIが実装されたようなクラスパス(CLASSPTH)によって見つけることができる. Apache Xercesに含まれるjarパッケージ.SPIインタフェースのコードは、特定の実装クラスをロードする必要があることが多い.JAXPの javax.xml.parsers.DocumentBuilderFactory
クラスの newInstance()
メソッドは新しい DocumentBuilderFactory
の例.ここでのインスタンスの真のクラスは、 javax.xml.parsers.DocumentBuilderFactory
SPIの実装により提供される.Apache Xercesで実装されるクラスは org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
.問題は、SPIのインタフェースがJavaコアライブラリの一部であり、ブートクラスローダによってロードされることである.SPIによって実装されるJavaクラスは、一般にシステムクラスローダによってロードされる.ブートクラスローダは、Javaのコアライブラリのみをロードするため、SPIの実装クラスを見つけることができません.システムクラスローダの祖先クラスローダであるため、システムクラスローダをエージェントすることもできません.すなわち,クラスローダのエージェントモードではこの問題を解決できない.スレッドコンテキストクラスローダはちょうどこの問題を解決した.何も設定しない場合、Javaアプリケーションのスレッドのコンテキストクラスローダはデフォルトでシステムコンテキストクラスローダです.SPIインタフェースのコードにスレッドコンテキストクラスローダを使用すると,SPI実装クラスへのロードに成功する.スレッドコンテキストクラスローダは、多くのSPIの実装で使用されます.
別のクラスをロードする方法を紹介します.
Class.forName
.Class.forName
Class.forName
クラスのロードにも使用できる静的メソッドです.この方法には、Class.forName(String name, boolean initialize, ClassLoader loader)
と Class.forName(String className)
.第1の形式のパラメータ name
クラスのフルネームを表す.initialize
クラスを初期化するか否かを示す.loader
ロード時に使用するクラスローダを示す.2つ目の形式はパラメータが設定されていることに相当します initialize
の値は true
,loader
の値は、現在のクラスのクラスローダです.Class.forName
データベースドライバをロードするときによく使われる使い方です.のように Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance()
Apache Derbyデータベースをロードするためのドライバ.おすすめ記事:
https://blog.csdn.net/zhoudaxia/article/details/35897057
https://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html