日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java provider_Java SPI(Service Provider Interface)

發(fā)布時間:2023/12/1 java 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java provider_Java SPI(Service Provider Interface) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

//ServiceLoader實現(xiàn)了Iterable接口,可以遍歷所有的服務實現(xiàn)者

public final class ServiceLoader

implements Iterable{//查找配置文件的目錄

private static final String PREFIX = "META-INF/services/";//表示要被加載的服務的類或接口

private final Classservice;//這個ClassLoader用來定位,加載,實例化服務提供者

private finalClassLoader loader;//訪問控制上下文

private finalAccessControlContext acc;//緩存已經被實例化的服務提供者,按照實例化的順序存儲

private LinkedHashMap providers = new LinkedHashMap<>();//The current lazy-lookup iterator

privateLazyIterator lookupIterator;//重新加載,就相當于重新創(chuàng)建ServiceLoader了,用于新的服務提供者安裝到正在運行的Java虛擬機中的情況

public voidreload() {//清空緩存中所有已實例化的服務提供者

providers.clear();//新建一個迭代器,該迭代器會從頭查找和實例化服務提供者

lookupIterator = newLazyIterator(service, loader);

}//私有構造器//使用指定的類加載器和服務創(chuàng)建服務加載器//如果沒有指定類加載器,使用系統(tǒng)類加載器,就是應用類加載器。

private ServiceLoader(Classsvc, ClassLoader cl) {

service= Objects.requireNonNull(svc, "Service interface cannot be null");

loader= (cl == null) ?ClassLoader.getSystemClassLoader() : cl;

acc= (System.getSecurityManager() != null) ? AccessController.getContext() : null;

reload();

}//解析失敗處理的方法

private static void fail(Class>service, String msg, Throwable cause)throwsServiceConfigurationError

{throw new ServiceConfigurationError(service.getName() + ": " +msg,

cause);

}private static void fail(Class>service, String msg)throwsServiceConfigurationError

{throw new ServiceConfigurationError(service.getName() + ": " +msg);

}private static void fail(Class> service, URL u, intline, String msg)throwsServiceConfigurationError

{

fail(service, u+ ":" + line + ": " +msg);

}//解析服務提供者配置文件中的一行//首先去掉注釋校驗,然后保存//返回下一行行號//重復的配置項和已經被實例化的配置項不會被保存

private int parseLine(Class> service, URL u, BufferedReader r, intlc,

Listnames)throwsIOException, ServiceConfigurationError

{//讀取一行

String ln =r.readLine();if (ln == null) {return -1;

}//#號代表注釋行

int ci = ln.indexOf('#');if (ci >= 0) ln = ln.substring(0, ci);

ln=ln.trim();int n =ln.length();if (n != 0) {if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0))

fail(service, u, lc,"Illegal configuration-file syntax");int cp = ln.codePointAt(0);if (!Character.isJavaIdentifierStart(cp))

fail(service, u, lc,"Illegal provider-class name: " +ln);for (int i = Character.charCount(cp); i < n; i +=Character.charCount(cp)) {

cp=ln.codePointAt(i);if (!Character.isJavaIdentifierPart(cp) && (cp != '.'))

fail(service, u, lc,"Illegal provider-class name: " +ln);

}if (!providers.containsKey(ln) && !names.contains(ln))

names.add(ln);

}return lc + 1;

}//解析配置文件,解析指定的url配置文件//使用parseLine方法進行解析,未被實例化的服務提供者會被保存到緩存中去

private Iterator parse(Class>service, URL u)throwsServiceConfigurationError

{

InputStream in= null;

BufferedReader r= null;

ArrayList names = new ArrayList<>();try{

in=u.openStream();

r= new BufferedReader(new InputStreamReader(in, "utf-8"));int lc = 1;while ((lc = parseLine(service, u, r, lc, names)) >= 0);

}catch(IOException x) {

fail(service,"Error reading configuration file", x);

}finally{try{if (r != null) r.close();if (in != null) in.close();

}catch(IOException y) {

fail(service,"Error closing configuration file", y);

}

}returnnames.iterator();

}//Private inner class implementing fully-lazy provider lookup//服務提供者查找的迭代器

private classLazyIteratorimplements Iterator{//服務提供者接口

Classservice;//類加載器

ClassLoader loader;//保存實現(xiàn)類的url

Enumeration configs = null;//保存實現(xiàn)類的全名

Iterator pending = null;//迭代器中下一個實現(xiàn)類的全名

String nextName = null;private LazyIterator(Classservice, ClassLoader loader) {this.service =service;this.loader =loader;

}private booleanhasNextService() {if (nextName != null) {return true;

}if (configs == null) {try{

String fullName= PREFIX +service.getName();if (loader == null)

configs=ClassLoader.getSystemResources(fullName);elseconfigs=loader.getResources(fullName);

}catch(IOException x) {

fail(service,"Error locating configuration files", x);

}

}while ((pending == null) || !pending.hasNext()) {if (!configs.hasMoreElements()) {return false;

}

pending=parse(service, configs.nextElement());

}

nextName=pending.next();return true;

}privateS nextService() {if (!hasNextService())throw newNoSuchElementException();

String cn=nextName;

nextName= null;

Class> c = null;try{

c= Class.forName(cn, false, loader);

}catch(ClassNotFoundException x) {

fail(service,"Provider " + cn + " not found");

}if (!service.isAssignableFrom(c)) {

fail(service,"Provider " + cn + " not a subtype");

}try{

S p=service.cast(c.newInstance());

providers.put(cn, p);returnp;

}catch(Throwable x) {

fail(service,"Provider " + cn + " could not be instantiated",

x);

}throw new Error(); //This cannot happen

}public booleanhasNext() {if (acc == null) {returnhasNextService();

}else{

PrivilegedAction action = new PrivilegedAction() {public Boolean run() { returnhasNextService(); }

};returnAccessController.doPrivileged(action, acc);

}

}publicS next() {if (acc == null) {returnnextService();

}else{

PrivilegedAction action = new PrivilegedAction() {public S run() { returnnextService(); }

};returnAccessController.doPrivileged(action, acc);

}

}public voidremove() {throw newUnsupportedOperationException();

}

}//獲取迭代器//返回遍歷服務提供者的迭代器//以懶加載的方式加載可用的服務提供者//懶加載的實現(xiàn)是:解析配置文件和實例化服務提供者的工作由迭代器本身完成

public Iteratoriterator() {return new Iterator() {//按照實例化順序返回已經緩存的服務提供者實例

Iterator>knownProviders=providers.entrySet().iterator();public booleanhasNext() {if(knownProviders.hasNext())return true;returnlookupIterator.hasNext();

}publicS next() {if(knownProviders.hasNext())returnknownProviders.next().getValue();returnlookupIterator.next();

}public voidremove() {throw newUnsupportedOperationException();

}

};

}//為指定的服務使用指定的類加載器來創(chuàng)建一個ServiceLoader

public static ServiceLoader load(Classservice,

ClassLoader loader)

{return new ServiceLoader<>(service, loader);

}//使用線程上下文的類加載器來創(chuàng)建ServiceLoader

public static ServiceLoader load(Classservice) {

ClassLoader cl=Thread.currentThread().getContextClassLoader();returnServiceLoader.load(service, cl);

}//使用擴展類加載器為指定的服務創(chuàng)建ServiceLoader//只能找到并加載已經安裝到當前Java虛擬機中的服務提供者,應用程序類路徑中的服務提供者將被忽略

public static ServiceLoader loadInstalled(Classservice) {

ClassLoader cl=ClassLoader.getSystemClassLoader();

ClassLoader prev= null;while (cl != null) {

prev=cl;

cl=cl.getParent();

}returnServiceLoader.load(service, prev);

}/*** Returns a string describing this service.

*

*@returnA descriptive string*/

publicString toString() {return "java.util.ServiceLoader[" + service.getName() + "]";

}

}

總結

以上是生活随笔為你收集整理的java provider_Java SPI(Service Provider Interface)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。