(4) java的spi

1.JAVA 的SPI機(jī)制

SPI全稱(service provider interface),是JDK內(nèi)置的一種服務(wù)提供發(fā)現(xiàn)機(jī)制塞琼,目前市面上有很多框架都是用它來做服務(wù)的擴(kuò)展發(fā)現(xiàn),大家耳熟能詳?shù)娜鏙DBC、日志框架都有用到序芦;

簡單來說愧沟,它是一種動(dòng)態(tài)替換發(fā)現(xiàn)的機(jī)制蔬咬。舉個(gè)簡單的例子,如果我們定義了一個(gè)規(guī)范央渣,需要第三方廠商去實(shí)現(xiàn)计盒,那么對(duì)于我們應(yīng)用方來說,只需要集成對(duì)應(yīng)廠商的插件芽丹,既可以完成對(duì)應(yīng)規(guī)范的實(shí)現(xiàn)機(jī)制北启。 形成一種插拔式的擴(kuò)展手段

2.實(shí)現(xiàn)一個(gè)SPI機(jī)制

  • 下面是自己來模擬spi來加載數(shù)據(jù)庫驅(qū)動(dòng)的流程圖
spi的流程圖.png
  • 數(shù)據(jù)庫的驅(qū)動(dòng)DataBaseDriver
/**
 * @Project: 3.DistributedProject
 * @description:  模擬數(shù)據(jù)庫的驅(qū)動(dòng)
 * @author: sunkang
 * @create: 2018-06-30 19:33
 * @ModificationHistory who      when       What
 **/
public interface DataBaseDriver {
    String connect(String url);
}
  • MysqlDriver的驅(qū)動(dòng)
/**
 * @Project:  java-spi
 * @description:   模擬MysqlDriver的驅(qū)動(dòng)
 * @author: sunkang
 * @create: 2018-06-30 19:34
 * @ModificationHistory who      when       What
 **/
public class MysqlDriver implements DataBaseDriver {
    @Override
    public String connect(String url) {
        return "mySql driver : "+url;
    }
}
  • 在資源目錄下的META-INF/services/目錄下新建com.java.spi.DataBaseDriver的文件
    com.java.spi.DataBaseDriver表示為接口的名稱蚊俺,com.java.spi.MysqlDriver為驅(qū)動(dòng)的具體實(shí)現(xiàn)類
com.java.spi.MysqlDriver
  • spi應(yīng)用的啟動(dòng)的例子
/**
* @Project: java-spi
* @description:  應(yīng)用的啟動(dòng)的例子
* @author: sunkang
* @create: 2018-06-30 19:33
* @ModificationHistory who      when       What
**/
public class JavaSpiDemo
{
   public static void main( String[] args )
   {
       ServiceLoader<DataBaseDriver> serviceLoader =ServiceLoader.load(DataBaseDriver.class);
       for(DataBaseDriver dataBaseDriver :serviceLoader){
           System.out.println(dataBaseDriver.connect("com.sunkang "));
       }
   }
}
  • 輸出結(jié)果為:
mySql driver : com.sunkang

3.SPI規(guī)范總結(jié)

實(shí)現(xiàn)SPI,就需要按照SPI本身定義的規(guī)范來進(jìn)行配置得封,SPI規(guī)范如下
1.需要在classpath下創(chuàng)建一個(gè)目錄,該目錄命名必須是:META-INF/services
2.在該目錄下創(chuàng)建一個(gè)文件拷呆,該文件需要滿足以下幾個(gè)條件

  • 文件名必須是擴(kuò)展的接口的全路徑名稱
  • 文件內(nèi)部描述的是該擴(kuò)展接口的所有實(shí)現(xiàn)類
  • 文件的編碼格式是UTF-8

3.通過java.util.ServiceLoader的加載機(jī)制來發(fā)現(xiàn)

4.SPI的實(shí)際應(yīng)用

SPI在很多地方有應(yīng)用,大家可以看看最常用的java.sql.Driver驅(qū)動(dòng)腰懂。JDK官方提供了java.sql.Driver這個(gè)驅(qū)動(dòng)擴(kuò)展點(diǎn)绣溜,但是你們并沒有看到JDK中有對(duì)應(yīng)的Driver實(shí)現(xiàn)涮毫。 那在哪里實(shí)現(xiàn)呢?

以連接Mysql為例咒吐,我們需要添加mysql-connector-java依賴属划。然后恬叹,你們可以在這個(gè)jar包中找到SPI的配置信息。如下圖,所以java.sql.Driver由各個(gè)數(shù)據(jù)庫廠商自行實(shí)現(xiàn)。這就是SPI的實(shí)際應(yīng)用。當(dāng)然除了這個(gè)意外的妖,大家在spring的包中也可以看到相應(yīng)的痕跡


5.SPI的缺點(diǎn)

1.JDK標(biāo)準(zhǔn)的SPI會(huì)一次性加載實(shí)例化擴(kuò)展點(diǎn)的所有實(shí)現(xiàn),什么意思呢忘蟹?就是如果你在META-INF/service下的文件里面加了N個(gè)實(shí)現(xiàn)類狠毯,那么JDK啟動(dòng)的時(shí)候都會(huì)一次性全部加載。那么如果有的擴(kuò)展點(diǎn)實(shí)現(xiàn)初始化很耗時(shí)或者如果有些實(shí)現(xiàn)類并沒有用到,那么會(huì)很浪費(fèi)資源
2.如果擴(kuò)展點(diǎn)加載失敗,會(huì)導(dǎo)致調(diào)用方報(bào)錯(cuò)颜及,而且這個(gè)錯(cuò)誤很難定位到是這個(gè)原因

6.ServiceLoader類的分析

     ServiceLoader<DataBaseDriver> serviceLoader =ServiceLoader.load(DataBaseDriver.class);
        for(DataBaseDriver dataBaseDriver :serviceLoader){
            System.out.println(dataBaseDriver.connect("com.sunkang "));
        }

public final class ServiceLoader<S> implements Iterable<S>該ServiceLoader實(shí)現(xiàn)了Iterable的接口墨林,具體了迭代器的功也就可以進(jìn)行for循環(huán)了

該load的方法會(huì)會(huì)初始化LazyIterator的迭代器

 public void reload() {
        providers.clear();
        lookupIterator = new LazyIterator(service, loader);
    }

那么的對(duì)應(yīng)引入的驅(qū)動(dòng)是如何發(fā)現(xiàn)并實(shí)例化的,可以猜想:
先通過掃描下 META-INF/services+接口名反浓,如果資源存在萌丈,則讀取具體的內(nèi)容進(jìn)行反射實(shí)例化
對(duì)應(yīng)的源碼這里就不解析了,的確也是這樣做的雷则。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末辆雾,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子月劈,更是在濱河造成了極大的恐慌度迂,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件猜揪,死亡現(xiàn)場(chǎng)離奇詭異惭墓,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)而姐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門腊凶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事钧萍『植” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵风瘦,是天一觀的道長队魏。 經(jīng)常有香客問我,道長万搔,這世上最難降的妖魔是什么胡桨? 我笑而不...
    開封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮瞬雹,結(jié)果婚禮上昧谊,老公的妹妹穿的比我還像新娘。我一直安慰自己酗捌,他們只是感情好揽浙,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著意敛,像睡著了一般馅巷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上草姻,一...
    開封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天钓猬,我揣著相機(jī)與錄音,去河邊找鬼撩独。 笑死敞曹,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的综膀。 我是一名探鬼主播澳迫,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼剧劝!你這毒婦竟也來了橄登?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤讥此,失蹤者是張志新(化名)和其女友劉穎拢锹,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體萄喳,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡卒稳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了他巨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片充坑。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡减江,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出捻爷,到底是詐尸還是另有隱情您市,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布役衡,位于F島的核電站,受9級(jí)特大地震影響薪棒,放射性物質(zhì)發(fā)生泄漏手蝎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一俐芯、第九天 我趴在偏房一處隱蔽的房頂上張望棵介。 院中可真熱鬧,春花似錦吧史、人聲如沸邮辽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吨述。三九已至,卻和暖如春钞脂,著一層夾襖步出監(jiān)牢的瞬間揣云,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來泰國打工冰啃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留邓夕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓阎毅,卻偏偏與公主長得像焚刚,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子扇调,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home...
    光劍書架上的書閱讀 3,865評(píng)論 2 8
  • SPI簡介 如何使用SPI 應(yīng)用舉例1. 組織方制定接口2. 實(shí)現(xiàn)方根據(jù)SPI規(guī)范實(shí)現(xiàn)接口3. 組織方加載實(shí)現(xiàn)類 ...
    齊晉閱讀 897評(píng)論 0 5
  • SPI矿咕,Service Provider Interface,主要是被框架的開發(fā)人員使用狼钮,比如java.sql.D...
    加大裝益達(dá)閱讀 1,684評(píng)論 2 12
  • 鐘梓晴的小委屈 “噗通痴腌!” 一個(gè)歐洲面孔的男人砰然倒地,剛剛還耀武揚(yáng)威的彪形大漢如今已經(jīng)變?yōu)橐痪呤w燃领。鐘梓晴將一枚...
    諾陽閣閱讀 452評(píng)論 0 0
  • 文/意磬 第二十八章 羅晉撥通班小闖的電話士聪,再次面對(duì)他的羞辱,甚至是有些無厘頭的責(zé)罵猛蔽“颍可是比起這些灵寺,他不能接受的是...
    意磬閱讀 1,328評(píng)論 14 32