クラスServiceLoader<S>
- 型パラメータ:
S- このローダーによってロードされるサービスのタイプ
- すべての実装されたインタフェース:
Iterable<S>
serviceは、ゼロ、1つ、または多数のサービス・プロバイダが存在する、よく知られているインタフェースまたはクラスです。 「サービス・プロバイダ」 (または単にprovider)は、よく知られているインタフェースまたはクラスを実装またはサブクラス化するクラスです。 ServiceLoaderは、アプリケーションの選択時にランタイ 環境にデプロイされたサービス・プロバイダを検出してロードするオブジェクトです。 アプリケーション・コードは、サービス・プロバイダを参照する けで、サービス・プロバイダを参照するものではなく、複数のサービス・プロバイダ(サービスを通じて公開される機能に基づいています)間を選択できると想定され、サービス・プロバイダが存在しない可能性が処理されます。
サービス・ローダーの入手
アプリケーションは、ServiceLoaderの静的なloadメソッドの1つを起動することによって、指定されたサービスのサービス・ローダーを取得します。 アプリケーションがモジュールの 合、そのモジュール宣言にはサービスを指定するusesディレクティブ文が必要です。プロバイダの 所を特定し、確実に実行されるようにします。 また、アプリケーション・モジュールにサービスが含まれていない 合、そのモジュール宣言には、サービスをエクスポートするモジュールを指定するrequiresディレクティブが必要です。 アプリケーション・モジュールでは、サービスのプロバイダを含むモジュールを必要としないことを強くお薦めします。
サービス・ローダーを使用して、iteratorメソッドを使用してサービスのプロバイダを特定し、インスタンス化することができます。 ServiceLoaderは、streamメソッドを定義して、インスタンス化せずに検査およびフィルタリングできるプロバイダのストリー を取得します。
例として、サービスがエンコーダとデコーダを生成するためのメソッドを定義するインタフェースであるcom.example.CodecFactoryであるとします:
package com.example;
public interface CodecFactory {
Encoder getEncoder(String encodingName);
Decoder getDecoder(String encodingName);
}
次のコードは、CodecFactoryサービスのサービス・ローダーを取得し、そのイテレータ(enhanced-forループによって自動的に作成される)を使用して、配置されているサービス・プロバイダのインスタンスを生成します:
ServiceLoader<CodecFactory> loader = ServiceLoader.load(CodecFactory.class);
for (CodecFactory factory : loader) {
Encoder enc = factory.getEncoder("PNG");
if (enc != null)
... use enc to encode a PNG file
break;
}
このコードがモジュールにある 合、com.example.CodecFactoryインタフェースを参照するために、モジュール宣言にはインタフェースをエクスポートするモジュールが必要です。 モジュール宣言では、com.example.CodecFactoryの使用も指定します:
requires com.example.codec.core;
uses com.example.CodecFactory;
サービス・プロバイダをインスタンス化する前に、そのサービス・プロバイダのインスタンスが有用かどうかを判断するために、アプリケーションがサービス・プロバイダを検査することが必要な 合があります。 例えば、 CodecFactoryのサービス・プロバイダは、"PNG"エンコーダを生成することができ、@PNGで注釈を付けることができます。 次のコードは、サービス・ローダーのstreamメソッドを使用して、イテレータがCodecFactoryのインスタンスを生成する方法とは対照的に、Provider<CodecFactory>のインスタンスを生成します:
ServiceLoader<CodecFactory> loader = ServiceLoader.load(CodecFactory.class);
Set<CodecFactory> pngFactories = loader
.stream() // Note a below
.filter(p -> p.type().isAnnotationPresent(PNG.class)) // Note b
.map(Provider::get) // Note c
.collect(Collectors.toSet());
-
Provider<CodecFactory>オブジェクトのストリー -
p.type()はClass<CodecFactory>を生成 -
get()はCodecFactoryのインスタンスを生成
サービスの設計
サービスは単一のタイプです。通常、インタフェースまたは抽象クラスです。 具体的なクラスを使用できますが、これはお勧めしません。 型にはアクセシビリティがある可能性があります。 サービスのメソッドは高度にドメイン固有であるため、このAPI仕様ではフォー または関数について具体的なアドバイスを行うことはできません。 た し、一般的なガイドラインは2つあります:
サービスは、サービス・プロバイダがドメイン固有のプロパティやその他の実装品質のファクタを伝えるために必要な数のメソッドを宣言する必要があります。 次に、サービスのサービス・ローダーを取得するアプリケーションは、アプリケーションのベスト・プロバイダを選択するために、サービス・プロバイダの各インスタンスでこれらのメソッドを呼び出すことができます。
サービスは、そのサービス・プロバイダがサービスの直接実装を意図しているのか、"proxy"や"factory"などの間接的なメカニズ であるのかを表現する必要があります。 サービス・プロバイダは、ドメイン固有のオブジェクトがインスタンス化するのに比較的高価な 合は間接的なメカニズ になりがちです。この 合、サービス・プロバイダは、オンデマンドで"real"実装を作成する抽象であるように設計する必要があります。 たとえば、
CodecFactoryサービスは、サービス・プロバイダがコーデック自体ではなくコーデックのファクトリであることをその名前で表しています。これは、特定のコーデックを生成するのが高価で複雑な 合があるためです。
サービス・プロバイダの開発
サービス・プロバイダは単一のタイプです。通常、コンクリート・クラスです。 インタフェースまたは抽象クラスは、後述する静的プロバイダ・メソッドを宣言できるため、許可されています。 型はパブリックである必要があり、内部クラスであってはなりません。
サービス・プロバイダとそのサポート・コードは、モジュールで開発され、アプリケーション・モジュールのパスまたはイメージにデプロイされます。 あるいは、サービス・プロバイダとそのサポート・コードをJARファイルとしてパッケージ化し、アプリケーション・クラス・パスにデプロイすることもできます。 モジュール内でサービス・プロバイダを開発する利点は、その実装のすべての詳細を すためにプロバイダを完全にカプセル化できることです。
特定のサービスのサービス・ローダーを取得するアプリケーションは、そのサービスのプロバイダがモジュールにデプロイされているのかJARファイルとしてパッケージ化されているのかは無関係です。 アプリケーションは、サービス・プロバイダのロケーションを把握せずに、サービス・ローダー・イテレータを介して、またはサービス・ローダー・ストリー 内のProviderオブジェクトを介してサービス・プロバイダをインスタンス化します。
サービス・プロバイダをモジュールとしてデプロイ
モジュールで開発されるサービス・プロバイダは、モジュール宣言のprovidesディレクティブで指定する必要があります。 provideディレクティブは、サービスとサービス・プロバイダの両方を指定します。これは、サービスのusesディレクティブを持つ別のモジュールがサービスのサービス・ローダーを取得したときに、プロバイダの位置を特定するのに役立ちます。 モジュールがサービス・プロバイダを含むパッケージをエクスポートしないことを強くお勧めします。 providesディレクティブで、別のモジュールのサービス・プロバイダを指定するモジュールのサポートはありません。
モジュール内で開発されたサービス・プロバイダは、インスタンス化された時点を制御できません。これは、アプリケーションの要求に応じて発生するためですが、インスタンス化の方法を制御します:
- サービス・プロバイダがプロバイダ・メソッドを宣言すると、サービス・ローダーはそのメソッドを呼び出して、サービス・プロバイダのインスタンスを取得します。 プロバイダ・メソッドは、"provider"という名前のパブリック静的メソッドで、仮パラメータおよびサービスのインタフェースまたはクラスに割り当てることができる戻り型はありません。
この 合、サービス・プロバイダ自体をサービスのインタフェースまたはクラスに割り当てる必要はありません。
- サービス・プロバイダがプロバイダ・メソッドを宣言しない 合、サービス・プロバイダはプロバイダ・コンストラクタを介して直接インスタンス化されます。 プロバイダ・コンストラクタは、仮パラメータを持たないパブリック・コンストラクタです。
この 合、サービス・プロバイダはサービスのインタフェースまたはクラスに割り当てることができる必要があります
アプリケーション・モジュールのパスに「自動モジュール」としてデプロイされるサービス・プロバイダには、プロバイダ・コンストラクタが必要です。 この 合、プロバイダ・メソッドはサポートされていません。
たとえば、モジュールで次のディレクティブが指定されているとします:
provides com.example.CodecFactory with com.example.impl.StandardCodecs,
com.example.impl.ExtendedCodecsFactory;
where
-
com.example.CodecFactoryは、以前の2メソッド・サービスです。 -
com.example.impl.StandardCodecsは、CodecFactoryを実装し、public no-argsコンストラクタを持つパブリック・クラスです。 -
com.example.impl.ExtendedCodecsFactoryは、CodecFactoryを実装していないパブリック・クラスですが、戻り値の型がCodecFactoryの"provider"というpublic static no-argsメソッドを宣言しています。
サービス・ローダーは、そのコンストラクタを介してStandardCodecsをインスタンス化し、そのproviderメソッドを呼び出すことによってExtendedCodecsFactoryをインスタンス化します。 プロバイダ・コンストラクタまたはプロバイダ・メソッドがpublicであるという要件は、クラス(つまり、サービス・プロバイダ)がクラスのパッケージ外にあるエンティティ(つまり、サービス・ローダー)によってインスタンス化されるというインテントを文書化するのに役立ちます。
クラスパスにサービス・プロバイダをデプロイ
クラスパスのJARファイルとしてパッケージ化されたサービス・プロバイダは、「プロバイダ構成ファイル」をリソース・ディレクトリMETA-INF/servicesに配置することによって識別されます。 プロバイダ構成ファイルの名前は、サービスの完全修飾バイナリ名です。 プロバイダ構成ファイルには、1行に1つずつ、サービス・プロバイダの完全修飾バイナリ名のリストが含まれています。
たとえば、サービス・プロバイダcom.example.impl.StandardCodecsがクラスパスのJARファイルにパッケージされているとします。 JARファイルには、次の名前のプロバイダ構成ファイルが含まれます:
META-INF/services/com.example.CodecFactory
次の行を含む:
com.example.impl.StandardCodecs # Standard codecs
プロバイダ構成ファイルは、UTF-8でエンコードする必要があります。 各サービス・プロバイダ名を囲む空白文字とタブ文字は無視されます。 コメント文字は'#' (U+0023 NUMBER SIGN)です。各行で、最初のコメント文字に続くすべての文字は無視されます。 サービス・プロバイダ・クラス名がプロバイダ構成ファイルに複数回リストされている 合、その複製は無視されます。 複数の構成ファイルでサービス・プロバイダ・クラスの名前が指定されている 合、その複製は無視されます。
プロバイダ構成ファイルに記述されているサービス・プロバイダは、プロバイダ構成ファイルと同じJARファイルまたは別のJARファイルにあります。 サービス・プロバイダは、プロバイダ構成ファイルを見つけるために最初に照会されたクラス・ローダーから可視でなければなりません。これは必ずしも最終的にプロバイダ構成ファイルを見つけるクラス・ローダーではありません。
プロバイダ発見のタイミング
サービス・プロバイダは、遅延して、つまり必要に応じてロードされ、インスタンス化されます。 サービス・ローダーは、以前にロードされたプロバイダのキャッシュを維持管理します。 iteratorメソッドを呼び出すたびに、Iteratorが返され、インスタンス化された 序でキャッシュされたすべての要 が最初に生成され、残りのプロバイダが遅延検索されてインスタンス化され、それぞれがキャッシュに 番に追 されます。 同様に、streamメソッドを呼び出すと、前のストリー 操作によってロードされたすべてのプロバイダを最初に処理し、ロードされた 番にStreamが返され、残りのプロバイダが遅延探索されます。 キャッシュはreloadメソッドでクリアされます。
Errors
サービス・ローダーのiteratorを使用すると、サービス・プロバイダの検索、ロードまたはインスタンス化でエラーが発生すると、hasNextおよびnextメソッドはServiceConfigurationErrorで失敗します。 サービス・ローダーのストリー を処理する 合、サービス・プロバイダを検出またはロードするメソッドによってServiceConfigurationErrorがスローされることがあります。
モジュール内でサービス・プロバイダをロードまたはインスタンス化する 合、次の理由により ServiceConfigurationErrorをスローすることができます:
- サービス・プロバイダをロードできません。
- サービス・プロバイダはプロバイダ・メソッドを宣言せず、サービスのインタフェース/クラスに割り当てられないか、プロバイダ・コンストラクタを持っていません。
- サービス・プロバイダは、"provider"という名前のpublic static no-argsメソッドを、サービスのインタフェースまたはクラスに割り当てられない戻り型で宣言します。
- サービス・プロバイダ・クラス・ファイルには、"
provider"という名前のpublic static no-argsメソッドが複数あります。 - サービス・プロバイダはプロバイダ・メソッドを宣言し、
nullを返すか例外をスローして失敗します。 - サービス・プロバイダはプロバイダ・メソッドを宣言せず、プロバイダ・コンストラクタは例外をスローすることによって失敗します。
プロバイダ構成ファイルを読み込むとき、またはプロバイダ構成ファイルで指定されたプロバイダ・クラスをロードまたはインスタンス化するときは、次の理由で ServiceConfigurationErrorをスローすることができます:
- プロバイダ構成ファイルの形式が上記のformatに違反しています。
-
IOExceptionがプロバイダ構成ファイルを読み取っているときに発生 - サービス・プロバイダはロードできません。
- サービス・プロバイダは、サービスのインタフェースまたはクラスに割り当てることができないか、プロバイダ・コンストラクタを定義しないか、またはインスタンス化できません。
同時実行性
このクラスのインスタンスは、複数のスレッドで並行して使用することはできません。
ヌル処理
特に指定しないかぎり、このクラスのメソッドにnull引数を渡すと、NullPointerExceptionがスローされます。
- 導入されたバージョン:
- 1.6
-
ネストされたクラスのサマリー
ネストされたクラス -
メソッドのサマリー
修飾子と型メソッド説明このローダーのサービスの最初の使用可能なサービス・プロバイダをロードします。iterator()このローダーのサービスの使用可能なプロバイダを遅延的にロードおよびインスタンス化するイテレータを返します。static <S> ServiceLoader<S> 指定されたサービス・タイプの新しいサービス・ローダーを、現在のスレッドのコンテキスト・クラス・ローダーを使って作成します。static <S> ServiceLoader<S> load(Class<S> service, ClassLoader loader) 指定されたサービスの新しいサービス・ローダーを作成します。static <S> ServiceLoader<S> load(ModuleLayer layer, Class<S> service) 指定されたモジュール・タイプおよびその祖先のモジュールからサービス・プロバイダをロードするために、指定されたサービス・タイプ用の新しいサービス・ローダーを作成します。static <S> ServiceLoader<S> loadInstalled(Class<S> service) 「プラットフォー ・クラス・ローダー」を使用して、指定されたサービス・タイプの新しいサービス・ローダーを作成します。voidreload()このローダーのプロバイダ・キャッシュをクリアし、すべてのプロバイダが再ロードされるようにします。stream()このローダーのサービスの使用可能なプロバイダを遅延的にロードするストリー を返します。toString()このサービスを記述した文字列を返します。クラスjava.lang.Objectで宣言されたメソッド
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitインタフェースjava.lang.Iterableで宣言されたメソッド
forEach, spliterator
-
メソッドの詳細
-
iterator
このローダーのサービスの使用可能なプロバイダを遅延的にロードおよびインスタンス化するイテレータを返します。惰を達成するために、プロバイダを特定してインスタンス化する実際の作業はイテレータ自体によって行われます。 そのため、
hasNextメソッドとnextメソッドは、上記の「エラー」セクションで指定された理由のいずれかによってServiceConfigurationErrorをスローすることができます。 ロバストなコードを書くには、イテレータを使用するときにServiceConfigurationErrorを捕捉する けでよい。 エラーがスローされた 合、その後のイテレータの呼び出しは、次に使用可能なプロバイダを特定してインスタンス化するために最善の努力をしますが、一般的にこのようなリカバリは保証できません。キャッシング: このメソッドによって返されるイテレータは、最初にプロバイダ・キャッシュのすべての要 を、ロードされた 序で返します。 その後、残りのサービス・プロバイダを遅延ロードしてインスタンス化し、各サービス・プロバイダを 次キャッシュに追 します。 このローダー・プロバイダ・キャッシュが
reloadメソッドを呼び出してクリアされた 合、このサービス・ローダーの既存のイテレータは 棄する必要があります。 イテレータのhasNextおよびnextメソッドは、プロバイダ・キャッシュがクリアされた後にConcurrentModificationExceptionをスローします。このメソッドから返されるイテレータは、削除をサポートしません。 その
removeメソッドを呼び出すと、UnsupportedOperationExceptionがスローされます。 -
stream
public Stream<ServiceLoader.Provider<S>> stream()このローダーのサービスの使用可能なプロバイダを遅延的にロードするストリー を返します。 ストリー 要 はProvider型で、プロバイダを取得またはインスタンス化するには、Providerのgetメソッドを起動する必要があります。惰を達成するために、ストリー を処理するときにプロバイダを見つける実際の作業が行われます。 上記の「エラー」セクションで指定された理由でサービス・プロバイダをロードできない 合、サービス・プロバイダをロードする原 となったメソッドによって
ServiceConfigurationErrorがスローされます。キャッシング: ストリー を処理するとき、ストリー 操作によって以前にロードされたプロバイダがロードされた に最初に処理されます。 その後、残りのサービス・プロバイダが遅延ロードされます。 このローダーのプロバイダ・キャッシュが
reloadメソッドを呼び出してクリアされた 合、このサービス・ローダーの既存のストリー は 棄する必要があります。 返されたストリー のソースspliteratorはfail-fastで、プロバイダ・キャッシュがクリアされるとConcurrentModificationExceptionがスローされます。次の例は、使用方法を示しています。 最初の例は
CodecFactoryオブジェクトのストリー を作成し、2番目の例はプロバイダ・クラス名(すべてのプロバイダを見つける)でプロバイダを並べ替える点を除いて同じです。Stream<CodecFactory> providers = ServiceLoader.load(CodecFactory.class) .stream() .map(Provider::get); Stream<CodecFactory> providers = ServiceLoader.load(CodecFactory.class) .stream() .sorted(Comparator.comparing(p -> p.type().getName())) .map(Provider::get);- 戻り値:
- このローダーのサービスのプロバイダを遅延ロードするストリー
- 導入されたバージョン:
- 9
-
load
public static <S> ServiceLoader<S> load(Class<S> service, ClassLoader loader) 指定されたサービスの新しいサービス・ローダーを作成します。 サービス・ローダーは、指定されたクラス・ローダーを開始点として使用して、サービスのサービス・プロバイダを特定します。 サービス・ローダーのiteratorおよびstreamは、次のように、名前付きモジュールと名前なしモジュールの両方でプロバイダを検索します:-
ステップ1: 名前付きモジュールでプロバイダを検索します。
サービス・プロバイダは、クラス・ローダーのすべての名前付きモジュールまたは親の委譲を介して到達可能な任意のクラス・ローダーにあります。
また、クラス・ローダーがブートストラップまたは「プラットフォー ・クラス・ローダー」でない 合、サービス・プロバイダは、他のクラス・ローダーの名前付きモジュールに配置できます。 具体的には、クラス・ローダー、または親委譲を介して到達可能なクラス・ローダーが「モジュール層」にモジュールを持つ 合、モジュール・レイヤー内のすべてのモジュールのサービス・プロバイダが配置されます。
たとえば、各モジュールが独自のクラス・ローダー(
defineModulesWithManyLoadersを参照してく さい)にあるモジュール・レイヤーがあるとします。 このServiceLoader.loadメソッドが呼び出されて、モジュール・レイヤー用に作成されたクラス・ローダーのいずれかを使用してプロバイダが見つかった 合は、定義しているクラス・ローダーに関係なく、モジュール・レイヤー内のすべてのプロバイダが検索されます。Ordering: サービス・ローダーは、まずクラス・ローダー、親クラス・ローダー、親親などに定義されたモジュール内のサービス・プロバイダをブートストラップ・クラス・ローダーに配置します。 クラス・ローダーがモジュール・レイヤーにモジュールを持つ 合、そのモジュール・レイヤー内のすべてのプロバイダは、親クラス・ローダーのプロバイダが配置される前に(クラス・ローダーに関係なく)に配置されます。 同じクラス・ローダー内のモジュールの 序付け、またはモジュール・レイヤー内のモジュールの 序付けは定義されていません。
モジュールが複数のプロバイダを宣言する 合、プロバイダはモジュール記述子「プロバイダを一覧表示」の 序で配置されます。 エージェント(
redefineModuleを参照してく さい)によって動的に追 されたプロバイダは、モジュールによって宣言されたプロバイダの後に常に配置されます。 -
ステップ2: 名前のないモジュールでプロバイダを探します。
名前のないモジュール内のサービス・プロバイダは、クラス・ローダーの
getResourcesメソッドにあるプロバイダ構成ファイルでクラス名がリストされている 合に配置されます。序付けは、クラス・ローダーの
getResourcesメソッドがサービス構成ファイルを検出する 序に基づいており、その中でクラス名がファイルにリストされる 序に基づいています。プロバイダ構成ファイルでは、名前付きモジュールにデプロイされているサービス・プロバイダの記述は無視されます。 これは、名前付きモジュールにprovidesディレクティブと同じサービス・プロバイダを記述するプロバイダ構成ファイルの両方がある 合に発生する重複を避けるためです。
プロバイダ・クラスは、クラス・ローダーから可視でなければなりません。
- APIのノート:
- クラス・ローダーのクラスパスにリモート・ネットワークURLが含まれている 合、それらのURLはプロバイダ構成ファイルの検索中に参照解除される可能性があります。
この活動は正常ですが、その 合、Webサーバーのログ内に不可解なエントリが作成される可能性があります。 た し、Webサーバーが正しく構成されていない 合には、この活動によってプロバイダ・ロード・アルゴリズ が擬似的に失敗する可能性があります。
要求されたリソースが存在しない 合、WebサーバーはHTTP 404 (Not Found)応答を返すべきです。 ところが、Webサーバーのなかには、そのような 合にHTTP 200 (OK)応答と有用なHTMLエラー・ページを返すように、間違って構成されているものもあります。 その 合、このクラスがそのHTMLページをプロバイダ構成ファイルとして解析しようとした時点で、
ServiceConfigurationErrorがスローされます。 この問題の最良の解決策は、間違って構成されたWebサーバーが正しい応答コード(HTTP 404)とHTMLエラー・ページを返すように、修正することです。 - 型パラメータ:
S- サービス・タイプのクラス- パラメータ:
service- サービスを表すインタフェースまたは抽象クラスloader- プロバイダ構成ファイルおよびプロバイダ・クラスのロードに使用されるクラス・ローダー、またはシステ ・クラス・ローダー(または、失敗した 合、ブートストラップ・クラス・ローダー)が使用される 合はnull- 戻り値:
- 新しいサービス・ローダー
- スロー:
ServiceConfigurationError- サービス型が呼び出し元にアクセスできない 合、または呼び出し元が明示的なモジュールにあり、そのモジュール記述子がserviceを使用していると宣言していない 合
-
-
load
public static <S> ServiceLoader<S> load(Class<S> service) 指定されたサービス・タイプの新しいサービス・ローダーを、現在のスレッドのコンテキスト・クラス・ローダーを使って作成します。このメソッドを次の形式で呼び出すと、上記の動作が行われます。
は、次のオプションに相当します。ServiceLoader.load(service)ServiceLoader.load(service, Thread.currentThread().getContextClassLoader())- APIのノート:
- このメソッドで取得したサービス・ローダー・オブジェクトは、VM全体でキャッシュしないでく さい。 たとえば、同じVM内の異なるアプリケーションが、異なるスレッド・コンテキスト・クラス・ローダーを持つ 合があります。 1つのアプリケーションによるルックアップでは、スレッド・コンテキスト・クラス・ローダーを介してのみ表示されるサービス・プロバイダを特定できるため、他のアプリケーションによる検索には適していません。 メモリー・リークが発生することもあります。 スレッド・ローカルは、一部のアプリケーションに適しています。
- 型パラメータ:
S- サービス・タイプのクラス- パラメータ:
service- サービスを表すインタフェースまたは抽象クラス- 戻り値:
- 新しいサービス・ローダー
- スロー:
ServiceConfigurationError- サービス型が呼び出し元にアクセスできない 合、または呼び出し元が明示的なモジュールにあり、そのモジュール記述子がserviceを使用していると宣言していない 合
-
loadInstalled
public static <S> ServiceLoader<S> loadInstalled(Class<S> service) 「プラットフォー ・クラス・ローダー」を使用して、指定されたサービス・タイプの新しいサービス・ローダーを作成します。この便利なメソッドは、次の指定と同じです。
ServiceLoader.load(service, ClassLoader.getPlatformClassLoader())このメソッドは、インストール済みのプロバイダ けが必要な 合に使用するためのものです。 結果のサービスは、現在のJava仮想マシンにインストールされているプロバイダのみを検索し、ロードします。アプリケーションのモジュール・パスまたはクラス・パスのプロバイダは無視されます。
- 型パラメータ:
S- サービス・タイプのクラス- パラメータ:
service- サービスを表すインタフェースまたは抽象クラス- 戻り値:
- 新しいサービス・ローダー
- スロー:
ServiceConfigurationError- サービス型が呼び出し元にアクセスできない 合、または呼び出し元が明示的なモジュールにあり、そのモジュール記述子がserviceを使用していると宣言していない 合
-
load
public static <S> ServiceLoader<S> load(ModuleLayer layer, Class<S> service) 指定されたモジュール・タイプおよびその祖先のモジュールからサービス・プロバイダをロードするために、指定されたサービス・タイプ用の新しいサービス・ローダーを作成します。 名前のないモジュールにはプロバイダが置かれていません。 サービス・ローダーのiteratorおよびstreamがプロバイダおよび歩留要 を検索する 序は、次のとおりです:プロバイダは、プロバイダを親レイヤーに配置する前にモジュール・レイヤーに配置されます。 親レイヤーの横断は深さ優先で、各レイヤーのアクセスは最大1回です。 たとえば、L0がブート層であり、L1およびL2がL0を親とするモジュール層であるとします。 ここで、L3がL1とL2を親(その 番で)として作成されたとします。 サービス・ローダーを使用して、コンテキストとしてL3を持つプロバイダを見つけると、次の 序でプロバイダが検索されます: L3, L1, L0, L2.
モジュールが複数のプロバイダを宣言する 合、プロバイダはモジュール記述子「プロバイダを一覧表示」の 序で配置されます。 エージェントによって動的に追 されたプロバイダは、モジュールによって宣言されたプロバイダの後に常に配置されます。
モジュール・レイヤーのモジュールの 序は定義されていません。
- APIのノート:
- ここで定義した他のロード・メソッドとは異なり、サービス・タイプは2番目のパラメータです。 この理由は、
load(S, null)を使用するコードのソースの互換性の問題を避けるためです。 - 型パラメータ:
S- サービス・タイプのクラス- パラメータ:
layer- モジュール層service- サービスを表すインタフェースまたは抽象クラス- 戻り値:
- 新しいサービス・ローダー
- スロー:
ServiceConfigurationError- サービス型が呼び出し元にアクセスできない 合、または呼び出し元が明示的なモジュールにあり、そのモジュール記述子がserviceを使用していると宣言していない 合- 導入されたバージョン:
- 9
-
findFirst
このローダーのサービスの最初の使用可能なサービス・プロバイダをロードします。 このコンビニエンス・メソッドは、iterator()メソッドを呼び出して最初の要 を取得することと同じです。 したがって、可能な 合はプロバイダ・キャッシュから最初の要 を返し、それ以外の 合は最初のプロバイダのロードとインスタンス化を試みます。次の例は、最初に利用可能なサービス・プロバイダを読み込みます。 サービス・プロバイダが見つからない 合は、デフォルトの実装が使用されます。
CodecFactory factory = ServiceLoader.load(CodecFactory.class) .findFirst() .orElse(DEFAULT_CODECSET_FACTORY);- 戻り値:
- 最初のサービス・プロバイダまたはサービス・プロバイダがない 合は空の
Optional - スロー:
ServiceConfigurationError- 上記の「エラー」セクションで指定された理由のいずれかでプロバイダ・クラスをロードできない 合。- 導入されたバージョン:
- 9
-
reload
-
toString
-