語言

ServiceLoader 類別

定義

一個載入服務實作的功能。

[Android.Runtime.Register("java/util/ServiceLoader", DoNotGenerateAcw=true)]
[Java.Interop.JavaTypeParameters(new System.String[] { "S" })]
public sealed class ServiceLoader : Java.Lang.Object, IDisposable, Java.Lang.IIterable
[<Android.Runtime.Register("java/util/ServiceLoader", DoNotGenerateAcw=true)>]
[<Java.Interop.JavaTypeParameters(new System.String[] { "S" })>]
type ServiceLoader = class
    inherit Object
    interface IIterable
    interface IJavaObject
    interface IDisposable
    interface IJavaPeerable
繼承
ServiceLoader
屬性
實作

備註

一個載入服務實作的功能。

服務是一種眾所周知的介面或類別,存在零、一個或多個服務提供者。 服務提供者(或簡稱提供者)是一個實作或子類的類別,負責實現或子類這個知名的介面或類別。 A ServiceLoader 是一個物件,負責在應用程式選擇的時間點定位並載入部署在執行時環境中的服務提供者。 應用程式碼僅指服務本身,不指服務提供者,且假設能根據服務中暴露的功能在多個服務提供者間做出選擇,並處理找不到服務提供者的可能性。

<h2> 取得服務裝載器 </h2>

應用程式透過調用 的load靜態ServiceLoader方法之一,獲得給定服務的服務載入器。 <--如果應用程式是模組,則其模組宣告必須包含指定服務的 使用 指令;這有助於找到服務提供者並確保他們能可靠執行。 此外,若應用模組不包含該服務,則其模組宣告必須包含 Required 指令,指定匯出服務的模組。 強烈建議應用程式模組 <b>not</b> 需要包含服務提供者的模組。--/>

服務載入器可用來定位並實例化服務 #iterator() iterator 提供者。 ServiceLoader 同時定義 #stream() stream 了取得可檢查與過濾的提供者流的方法,無需實例化。

舉例來說,假設服務為 com.example.CodecFactory,一個定義產生編碼器和解碼器方法的介面:

{@code
                package com.example;
                public interface CodecFactory {
                    Encoder getEncoder(String encodingName);
                    Decoder getDecoder(String encodingName);
                }
            }

以下程式碼取得服務載入器 CodecFactory ,然後使用其迭代器(由增強的 for 迴圈自動建立)產生服務提供者的實例:

{@code
                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;
                    }
            }

有時應用程式會希望在實例化服務提供者前檢查該服務提供者,以判斷該服務提供者的實例是否有用。 例如,一個能夠產生「PNG」編碼器的服務提供者 CodecFactory ,可能會標註 @PNG。 以下程式碼使用服務載入者的方法 stream 來產生 的 Provider<CodecFactory> 實例,與迭代器產生的 CodecFactory實例形成對比:

{@code
                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());
            }

<ol 類型=“a”>li 一連<串物件 >/liProvider<CodecFactory><li>< 產生>p.type() /liClass<CodecFactory><>< li 產生 /li>get()/ol 的實例CodecFactory<><>

<h2> 設計服務 </h2>

服務是一種單一類型,通常是介面類別或抽象類別。 雖然可以使用具體類別,但不建議這麼做。 該類型可能具備任何無障礙性。 服務的方法高度依賴領域特定,因此本 API 規範無法對其形式或功能提供具體建議。 不過,有兩個一般原則: <ol><li>

服務應宣告盡可能多的方法,以允許服務提供者傳達其領域專屬屬性及其他實作品質因素。 取得服務載入器的應用程式,可以在每個服務提供者實例上呼叫這些方法,以選擇最適合該應用程式的提供者。

</李><莉>

服務應明確表示其服務提供者是直接實作服務,還是作為間接機制,如「代理」或「工廠」。 當領域特定物件實例化成本較高時,服務提供者往往是間接機制;在這種情況下,服務應設計成服務提供者是抽象體,能隨需創造「真實」實作。 例如,該 CodecFactory 服務透過名稱表達其服務提供者是編解碼器的工廠,而非編解碼器本身,因為生產某些編解碼器可能成本高昂或複雜。

</li></ol>

<h2> 「開發服務提供者」發展>服務提供者</h2>

服務提供者是一種單一類型,通常是具體類別。 允許介面或抽象類別,因為它可能宣告靜態提供者方法,稍後會討論。 該類型必須是公開的,且不能是內部類別。

服務提供者及其支援程式碼可在模組中開發,然後部署於應用程式模組路徑或模組化映像中。 或者,服務提供者及其支援程式碼也可以 JAR 檔案形式打包,部署於應用程式類別路徑上。 以模組開發服務提供者的優點在於,該提供者可以被完全封裝,隱藏其實作的所有細節。

取得服務載入器的應用程式,對於該服務提供者是以模組形式部署或以 JAR 檔案封裝,並不介意。 應用程式透過服務載入器的迭代器,或服務 Provider Provider 載入器串流中的物件實例化服務提供者,且不了解服務提供者的位置。

<h2> 在類別路徑 </h2 部署服務提供者>

以 JAR 檔案封裝為類別路徑的服務提供者,透過在資源目錄中放置META-INF/services來識別。 提供者設定檔的名稱是服務的完全限定二進位名稱。 提供者設定檔包含一份完全限定的服務提供者二進位名稱清單,每行一個。

例如,假設服務提供者 com.example.impl.StandardCodecs 被封裝在類別路徑的 JAR 檔案中。 JAR 檔案將包含一個名為:

<引用>META-INF/services/com.example.CodecFactory</引用>

其中包含以下行:

<引用>com.example.impl.StandardCodecs # Standard codecs</引用>

“format”>提供者設定檔必須以 UTF-8 編碼。 每個服務提供者名稱周圍的空白與制表字元,以及空白行都被忽略。 註解字元為 '#' (U+0023<span style=“font-size:smaller;”>NUMBER sign/span<)>;在每行中,第一個註解字元之後的所有字元都會被忽略。 如果服務提供者類別名稱在提供者設定檔中列出超過一次,則該重複名稱會被忽略。 如果一個服務提供者類別在多個組態檔中被命名,則該重複會被忽略。

提供者設定檔中提及的服務提供者可能位於與提供者設定檔相同的 JAR 檔案中,或是不同的 JAR 檔案中。 服務提供者必須在最初查詢的類別載入器中可見,以定位提供者設定檔;這不一定是最終定位提供者設定檔的類別載入器。

<h2> 提供者發現 <的時間點 /h2>

服務提供者被懶散地載入和實例化,也就是按需。 服務載入器會維護已載入的提供者快取。 每次呼叫該 iterator 方法會回傳 , Iterator 先依實例化順序提供前一次迭代中快取的所有元素,然後懶惰地尋找並實例化剩餘的提供者,逐一加入快取。 同樣地,每次呼叫串流方法都會回傳一個,該 會 Stream 先依載入順序處理先前串流操作載入的所有提供者,然後懶惰地尋找剩餘提供者。 快取是透過此 #reload reload 方法清除的。

<h2> 「錯誤」>錯誤/<h2>

使用服務載入器的 iterator時, Iterator#hasNext() hasNext 若在定位、載入或實例化服務提供者時發生錯誤,且 和 Iterator#next() next 方法將失敗 ServiceConfigurationError 。 在處理服務載入器 ServiceConfigurationError 時,任何能定位或載入服務提供者的方法都會拋出服務載入串流。

在模組中載入或實例化服務提供者時, ServiceConfigurationError 可能會因以下原因拋棄:

當讀取提供者設定檔,或載入或實例化提供者設定檔中命名的提供者類別時,可能會 ServiceConfigurationError 拋出以下原因:

<UL>

<li> 提供者設定檔的格式違反上述格式; </李>

<li> An IOException IOException 發生在讀取提供者設定檔時; </李>

<li> 無法載入服務提供者; </李>

<li> 服務提供者無法指派到服務的介面或類別,或不定義提供者建構子,或無法實例化。 </李>

</ul>

<h2> 並行 </h2>

此類別的實例不適合多個並行執行緒使用。

<h3> 空處理 </h3>

除非另有說明,將參數傳給 null 此類別中的任何方法都會導致拋出 a NullPointerException 。

新增於1.6版本。

Java 文件 java.util.ServiceLoader。

本頁部分內容為基於 Open Source Project 所創建與分享的作品,並依授權條款所描述的使用進行修改。

屬性

名稱 Description
Class

回傳此 Object的執行時類別。

(繼承來源 Object)
Handle

底層 Android 實例的帳號。

(繼承來源 Object)
JniIdentityHashCode

取得由互通執行時指派給此 Java 對等端的身份雜湊碼。

(繼承來源 Object)
JniManagedPeerState

一個載入服務實作的功能。

(繼承來源 JavaObject)
JniPeerMembers

一個載入服務實作的功能。

PeerReference

取得這個 Java 節點的 JNI 物件參考。

(繼承來源 Object)
ThresholdClass

此 API 支援 Mono for Android 基礎架構,並非直接從你的程式碼中使用。

(繼承來源 Object)
ThresholdType

此 API 支援 Mono for Android 基礎架構,並非直接從你的程式碼中使用。

(繼承來源 Object)

方法

名稱 Description
Clone()

建立並回傳此物件的副本。

(繼承來源 Object)
Construct(JniObjectReference, JniObjectReferenceOptions)

一個載入服務實作的功能。

(繼承來源 JavaObject)
Dispose()

釋放該 Java 節點所持有的資源。

(繼承來源 Object)
Dispose(Boolean)

釋放該 Java 節點所持有的資源。

(繼承來源 Object)
DisposeUnlessReferenced()

一個載入服務實作的功能。

(繼承來源 JavaObject)
Equals(Object)

一個載入服務實作的功能。

(繼承來源 JavaObject)
Equals(Object)

表示是否有其他物體「等同」於此物。

(繼承來源 Object)
FindFirst()

載入該載入器服務的第一個可用服務提供者。

GetHashCode()

回傳物件的雜湊碼值。

(繼承來源 Object)
Iterator()

懶散地載入該載入服務提供者。

JavaFinalize()
已淘汰.

當垃圾回收判定該物件不再有相關參考時,由垃圾回收器呼叫。

(繼承來源 Object)
Load(Class, ClassLoader)

為指定的服務類型與類別載入器建立新的服務載入器。

Load(Class)

利用目前執行緒的 Java 為該服務類型建立新的服務載入器。

LoadInstalled(Class)

利用擴充類別載入器為該服務類型建立新的服務載入器。

Notify()

喚醒一個正在該物件監視器上等待的執行緒。

(繼承來源 Object)
NotifyAll()

喚醒所有等待該物件監視器的執行緒。

(繼承來源 Object)
Reload()

清除這個載入器的提供者快取,讓所有提供者都會重新載入。

SetHandle(IntPtr, JniHandleOwnership)

設定 Handle 屬性。

(繼承來源 Object)
SetPeerReference(JniObjectReference, JniObjectReferenceOptions)

一個載入服務實作的功能。

(繼承來源 JavaObject)
ToArray<T>()

從這個 Java 陣列包裝器建立一個受管理陣列。

(繼承來源 Object)
ToString()

回傳物件的字串表示。

(繼承來源 Object)
UnregisterFromRuntime()

將此 Java 節點從互通執行時中取消註冊。

(繼承來源 Object)
Wait()

導致目前執行緒等待被喚醒,通常是透過 <em>通知</><em 或 em>中斷</em> 來喚醒。

(繼承來源 Object)
Wait(Int64, Int32)

會讓目前執行緒等待喚醒,通常是透過 <em>通知</><em 或 em>中斷</em>,或是經過一定的真實時間。

(繼承來源 Object)
Wait(Int64)

會讓目前執行緒等待喚醒,通常是透過 <em>通知</><em 或 em>中斷</em>,或是經過一定的真實時間。

(繼承來源 Object)

明確介面實作

名稱 Description
IJavaPeerable.Disposed()

一個載入服務實作的功能。

(繼承來源 JavaObject)
IJavaPeerable.Finalized()

一個載入服務實作的功能。

(繼承來源 JavaObject)
IJavaPeerable.JniObjectReferenceControlBlock

一個載入服務實作的功能。

(繼承來源 JavaObject)
IJavaPeerable.SetJniIdentityHashCode(Int32)

一個載入服務實作的功能。

(繼承來源 JavaObject)
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates)

一個載入服務實作的功能。

(繼承來源 JavaObject)
IJavaPeerable.SetPeerReference(JniObjectReference)

一個載入服務實作的功能。

(繼承來源 JavaObject)
IJavaPeerable.UnregisterFromRuntime()

一個載入服務實作的功能。

擴充方法

名稱 Description
GetJniTypeName(IJavaPeerable)

取得實例 self類型的 JNI 名稱。

JavaAs<TResult>(IJavaPeerable)

試著強制self輸入 TResult,檢查 強制在 Java 端是否有效。

JavaCast<TResult>(IJavaObject)

執行 Android 執行時檢查型別轉換。

JavaCast<TResult>(IJavaObject)

一個載入服務實作的功能。

ToEnumerable(IIterable)

回傳 和 IEnumerable ,會對 Java IIterable進行迭代,允許 foreach 和 LINQ 與 Java 集合類型一起使用。 每個元素都會從其 Java 實例編組到對應的受管理型別。

ToEnumerable<T>(IIterable)

回傳 和 IEnumerable<T> ,該 在 Java IIterable上迭代,將每個元素 集結為 T。 這使得 foreach LINQ 可以搭配 Java 集合類型一起使用。

TryJavaCast<TResult>(IJavaPeerable, TResult)

試著強制self輸入 TResult,檢查 強制在 Java 端是否有效。

適用於