W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
java.lang.Object
|---java.util.ServiceLoader<S&
public final class ServiceLoader<S>
extends Object
implements Iterable<S>
一個(gè)簡(jiǎn)單的服務(wù)提供者加載工具。
服務(wù)是一組眾所周知的接口和(通常是抽象的)類。 服務(wù)提供者是服務(wù)的具體實(shí)現(xiàn)。 提供者中的類通常實(shí)現(xiàn)服務(wù)本身中定義的類的接口和子類。 服務(wù)提供者可以以擴(kuò)展的形式安裝在 Java 平臺(tái)的實(shí)現(xiàn)中,即將 jar 文件放置在任何常用的擴(kuò)展目錄中。 還可以通過將提供程序添加到應(yīng)用程序的類路徑或通過某些其他特定于平臺(tái)的方式來使提供程序可用。
出于加載的目的,服務(wù)由單一類型表示,即單一接口或抽象類。 (可以使用具體類,但不建議這樣做。)給定服務(wù)的提供者包含一個(gè)或多個(gè)具體類,這些具體類使用提供者特定的數(shù)據(jù)和代碼擴(kuò)展此服務(wù)類型。 提供者類通常不是整個(gè)提供者本身,而是一個(gè)代理,它包含足夠的信息來決定提供者是否能夠滿足特定請(qǐng)求以及可以按需創(chuàng)建實(shí)際提供者的代碼。 提供者類的細(xì)節(jié)往往是高度特定于服務(wù)的; 沒有一個(gè)類或接口可以統(tǒng)一它們,所以這里沒有定義這樣的類型。 此工具強(qiáng)制執(zhí)行的唯一要求是提供程序類必須具有零參數(shù)構(gòu)造函數(shù),以便它們可以在加載期間被實(shí)例化。
通過在資源目錄 META-INF/services 中放置提供者配置文件來識(shí)別服務(wù)提供者。 該文件的名稱是服務(wù)類型的完全限定二進(jìn)制名稱。 該文件包含具體提供程序類的完全限定二進(jìn)制名稱列表,每行一個(gè)。 每個(gè)名稱周圍的空格和制表符以及空白行將被忽略。 注釋字符為'#'('\u0023', NUMBER SIGN); 在每一行中,第一個(gè)注釋字符之后的所有字符都將被忽略。 該文件必須以 UTF-8 編碼。
如果一個(gè)特定的具體提供者類在多個(gè)配置文件中被命名,或者在同一個(gè)配置文件中被命名不止一次,那么重復(fù)的將被忽略。 命名特定提供者的配置文件不必與提供者本身位于相同的 jar 文件或其他分發(fā)單元中。 必須可以從最初查詢配置文件的同一個(gè)類加載器訪問提供程序; 請(qǐng)注意,這不一定是實(shí)際加載文件的類加載器。
提供者的定位和實(shí)例化是惰性的,即按需。 服務(wù)加載器維護(hù)到目前為止已加載的提供程序的緩存。 迭代器方法的每次調(diào)用都會(huì)返回一個(gè)迭代器,它首先按實(shí)例化順序產(chǎn)生緩存的所有元素,然后延遲定位并實(shí)例化任何剩余的提供者,依次將每個(gè)提供者添加到緩存中。 可以通過 reload 方法清除緩存。
服務(wù)加載程序總是在調(diào)用者的安全上下文中執(zhí)行。 受信任的系統(tǒng)代碼通常應(yīng)該從特權(quán)安全上下文中調(diào)用此類中的方法以及它們返回的迭代器的方法。
此類的實(shí)例對(duì)于多個(gè)并發(fā)線程的使用是不安全的。
除非另有說明,否則將 null 參數(shù)傳遞給此類中的任何方法都將導(dǎo)致拋出 NullPointerException。
示例 假設(shè)我們有一個(gè)服務(wù)類型 com.example.CodecSet,它旨在表示某些協(xié)議的編碼器/解碼器對(duì)集合。 在這種情況下,它是一個(gè)具有兩個(gè)抽象方法的抽象類:
public abstract Encoder getEncoder(String encodingName);
public abstract Decoder getDecoder(String encodingName);
如果提供者不支持給定的編碼,每個(gè)方法都會(huì)返回一個(gè)適當(dāng)?shù)膶?duì)象或 null。 典型的供應(yīng)商支持不止一種編碼。
如果 com.example.impl.StandardCodecs 是 CodecSet 服務(wù)的實(shí)現(xiàn),那么它的 jar 文件還包含一個(gè)名為
META-INF/services/com.example.CodecSet
該文件包含一行:
com.example.impl.StandardCodecs # Standard codecs
CodecSet 類在初始化時(shí)創(chuàng)建并保存單個(gè)服務(wù)實(shí)例:
private static ServiceLoader<CodecSet> codecSetLoader
= ServiceLoader.load(CodecSet.class);
為了找到給定編碼名稱的編碼器,它定義了一個(gè)靜態(tài)工廠方法,該方法遍歷已知和可用的提供程序,僅在找到合適的編碼器或用完提供程序時(shí)返回。
public static Encoder getEncoder(String encodingName) {
for (CodecSet cp : codecSetLoader) {
Encoder enc = cp.getEncoder(encodingName);
if (enc != null)
return enc;
}
return null;
}
getDecoder 方法的定義類似。
使用說明 如果用于加載提供程序的類加載器的類路徑包含遠(yuǎn)程網(wǎng)絡(luò) URL,則在搜索提供程序配置文件的過程中將取消引用這些 URL。
此活動(dòng)是正常的,盡管它可能會(huì)導(dǎo)致在 Web 服務(wù)器日志中創(chuàng)建令人費(fèi)解的條目。但是,如果未正確配置 Web 服務(wù)器,則此活動(dòng)可能會(huì)導(dǎo)致提供程序加載算法虛假失敗。
當(dāng)請(qǐng)求的資源不存在時(shí),Web 服務(wù)器應(yīng)返回 HTTP 404(未找到)響應(yīng)。但是,有時(shí) Web 服務(wù)器被錯(cuò)誤地配置為在這種情況下返回 HTTP 200 (OK) 響應(yīng)以及有用的 HTML 錯(cuò)誤頁面。當(dāng)此類嘗試將 HTML 頁面解析為提供程序配置文件時(shí),這將導(dǎo)致拋出 ServiceConfigurationError。此問題的最佳解決方案是修復(fù)錯(cuò)誤配置的 Web 服務(wù)器以返回正確的響應(yīng)代碼 (HTTP 404) 以及 HTML 錯(cuò)誤頁面。
修飾符和類型 | 方法 | 描述 |
---|---|---|
IteratorS | iterator() | 延遲加載此加載程序服務(wù)的可用提供程序。 |
static <S> ServiceLoader<S> | load(Class<S> service) | 使用當(dāng)前線程的上下文類加載器為給定的服務(wù)類型創(chuàng)建一個(gè)新的服務(wù)加載器。 |
static <S> ServiceLoader<S> | load(Class<S> service, ClassLoader loader) | 為給定的服務(wù)類型和類加載器創(chuàng)建一個(gè)新的服務(wù)加載器。 |
static <S> ServiceLoader<S> | loadInstalled(Class<S> service) | 使用擴(kuò)展類加載器為給定的服務(wù)類型創(chuàng)建一個(gè)新的服務(wù)加載器。 |
void | reload() | 清除此加載器的提供程序緩存,以便重新加載所有提供程序。 |
String | toString() | 返回描述此服務(wù)的字符串。 |
從接口 java.lang.Iterable 繼承的方法 |
---|
forEach, spliterator |
從類 java.lang.Object 繼承的方法 |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
public void reload()
清除此加載器的提供程序緩存,以便重新加載所有提供程序。
調(diào)用此方法后,迭代器方法的后續(xù)調(diào)用將懶惰地從頭開始查找并實(shí)例化提供程序,就像新創(chuàng)建的加載程序所做的那樣。
此方法適用于可以將新提供程序安裝到正在運(yùn)行的 Java 虛擬機(jī)中的情況。
public IteratorS iterator()
延遲加載此加載程序服務(wù)的可用提供程序。
此方法返回的迭代器首先按實(shí)例化順序生成提供程序緩存的所有元素。 然后它會(huì)延遲加載并實(shí)例化任何剩余的提供者,依次將每個(gè)提供者添加到緩存中。
為了實(shí)現(xiàn)惰性,解析可用提供程序配置文件和實(shí)例化提供程序的實(shí)際工作必須由迭代器本身完成。 因此,如果提供程序配置文件違反了指定格式,或者如果它命名了無法找到和實(shí)例化的提供程序類,或者如果實(shí)例化類的結(jié)果不能分配給服務(wù)類型,則它的 hasNext 和 next 方法可以拋出 ServiceConfigurationError ,或者在定位和實(shí)例化下一個(gè)提供程序時(shí)引發(fā)任何其他類型的異?;蝈e(cuò)誤。 要編寫健壯的代碼,只需要在使用服務(wù)迭代器時(shí)捕獲 ServiceConfigurationError。
如果拋出這樣的錯(cuò)誤,那么迭代器的后續(xù)調(diào)用將盡最大努力定位和實(shí)例化下一個(gè)可用的提供程序,但通常不能保證這樣的恢復(fù)。
設(shè)計(jì)說明 在這些情況下拋出錯(cuò)誤可能看起來很極端。 這種行為的基本原理是格式錯(cuò)誤的提供程序配置文件(如格式錯(cuò)誤的類文件)表明 Java 虛擬機(jī)的配置或使用方式存在嚴(yán)重問題。 因此,最好拋出錯(cuò)誤而不是嘗試恢復(fù),或者更糟糕的是,靜默失敗。
此方法返回的迭代器不支持移除。 調(diào)用它的 remove 方法將導(dǎo)致拋出 UnsupportedOperationException。
指定者:
接口 IterableS 中的迭代器
返回:
延遲加載此加載器服務(wù)的提供程序的迭代器
public static <S> ServiceLoader<S> load(Class<S> service, ClassLoader loader)
為給定的服務(wù)類型和類加載器創(chuàng)建一個(gè)新的服務(wù)加載器。
類型參數(shù):
類型參數(shù)名稱 | 類型參數(shù)描述 |
---|---|
S | 服務(wù)類型的類 |
參數(shù):
參數(shù)名稱 | 參數(shù)描述 |
---|---|
service | 表示服務(wù)的接口或抽象類 |
loader | 用于加載提供程序配置文件和提供程序類的類加載器,如果要使用系統(tǒng)類加載器(或者,如果失敗,則為引導(dǎo)類加載器),則為 null |
返回:
一個(gè)新的服務(wù)加載器
public static <S> ServiceLoader<S> load(Class<S> service)
使用當(dāng)前線程的上下文類加載器為給定的服務(wù)類型創(chuàng)建一個(gè)新的服務(wù)加載器。
調(diào)用表單的這種便捷方法
ServiceLoader.load(service)
相當(dāng)于
ServiceLoader.load(service,
Thread.currentThread().getContextClassLoader())
類型參數(shù):
類型參數(shù)名稱 | 類型參數(shù)描述 |
---|---|
S | 服務(wù)類型的類 |
參數(shù):
參數(shù)名稱 | 參數(shù)描述 |
---|---|
service | 表示服務(wù)的接口或抽象類 |
返回:
一個(gè)新的服務(wù)加載器
public static <S> ServiceLoader<S> loadInstalled(Class<S> service)
使用擴(kuò)展類加載器為給定的服務(wù)類型創(chuàng)建一個(gè)新的服務(wù)加載器。
這個(gè)方便的方法只是簡(jiǎn)單的定位擴(kuò)展類加載器,調(diào)用它extClassLoader,然后返回
ServiceLoader.load(service, extClassLoader)
如果找不到擴(kuò)展類加載器,則使用系統(tǒng)類加載器; 如果沒有系統(tǒng)類加載器,則使用引導(dǎo)類加載器。
此方法旨在僅在需要已安裝的提供程序時(shí)使用。 生成的服務(wù)只會(huì)查找并加載已安裝到當(dāng)前 Java 虛擬機(jī)中的提供程序; 應(yīng)用程序類路徑上的提供者將被忽略。
類型參數(shù):
類型參數(shù)名稱 | 類型參數(shù)描述 |
---|---|
S | 服務(wù)類型的類 |
參數(shù):
參數(shù)名稱 | 參數(shù)描述 |
---|---|
service | 表示服務(wù)的接口或抽象類 |
返回:
一個(gè)新的服務(wù)加載器
public String toString()
返回描述此服務(wù)的字符串。
覆蓋:
類 Object 中的 toString
返回:
描述性字符串
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: