最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java SPI 機(jī)制知識(shí)點(diǎn)總結(jié)

 更新時(shí)間:2020年02月24日 10:39:45   作者:crossoverJie  
在本篇文章里小編給大家整理的是一篇關(guān)于Java SPI 機(jī)制知識(shí)點(diǎn)總結(jié)內(nèi)容,需要的朋友們可以參考下。

前言

不知大家現(xiàn)在有沒有去公司復(fù)工,我已經(jīng)在家辦公將近 3 周了,同時(shí)也在家呆了一個(gè)多月;還好工作并沒有受到任何影響,我個(gè)人一直覺得遠(yuǎn)程工作和 IT 行業(yè)是非常契合的,這段時(shí)間的工作效率甚至比在辦公室還高,同時(shí)由于我們公司的業(yè)務(wù)在海外,所以疫情幾乎沒有造成太多影響。

扯遠(yuǎn)了,這次主要是想和大家分享一下 Java 的 SPI 機(jī)制。

還沒看過的朋友的我先做個(gè)前景提要,當(dāng)時(shí)的需求:

我實(shí)現(xiàn)了一個(gè)類似于的 SpringMVC 但卻很輕量的 http 框架 cicada,其中當(dāng)然也需要一個(gè) IOC 容器,可以存放所有的單例 bean。

這個(gè) IOC 容器的實(shí)現(xiàn)我希望可以有多種方式,甚至可以提供一個(gè)接口供其他人實(shí)現(xiàn);當(dāng)然切換這個(gè) IOC 容器的過程肯定是不能存在硬編碼的,也就是這里所提到的可拔插。當(dāng)我想使用 A 的實(shí)現(xiàn)方式時(shí),我就引入 A 的 jar 包,使用 B 時(shí)就引入 B 的包。

先給大家看看兩次實(shí)現(xiàn)的區(qū)別,先從代碼簡潔程度來說就是 SPI 更勝一籌。

什么是 SPI

在具體分析之前還是先了解下 SPI 是什么?

首先它其實(shí)是 Service provider interface 的簡寫,翻譯成中文就是服務(wù)提供發(fā)現(xiàn)接口。

不過這里不要被這個(gè)名詞搞混了,這里的服務(wù)發(fā)現(xiàn)和我們常聽到的微服務(wù)中的服務(wù)發(fā)現(xiàn)并不能劃等號(hào)。

就如同上文提到的對(duì) IOC 容器的多種實(shí)現(xiàn)方式 A、B、C(可以把它們理解為服務(wù)),我需要在運(yùn)行時(shí)知道應(yīng)該使用哪一種具體的實(shí)現(xiàn)。

其實(shí)本質(zhì)上來說這就是一種典型的面向接口編程,這一點(diǎn)在我們剛開始學(xué)習(xí)編程的時(shí)候就被反復(fù)強(qiáng)調(diào)了。

SPI 實(shí)踐

接下來我們來如何來利用 SPI 實(shí)現(xiàn)剛才提到的可拔插 IOC 容器。

既然剛才都提到了 SPI 的本質(zhì)就是面向接口編程,所以自然我們首先需要定義一個(gè)接口:

其中包含了一些 Bean 容器所必須的操作:注冊(cè)、獲取、釋放 bean。

為了讓其他人也能實(shí)現(xiàn)自己的 IOC 容器,所以我們將這個(gè)接口單獨(dú)放到一個(gè) Module 中,可供他人引入實(shí)現(xiàn)。

所以當(dāng)我要實(shí)現(xiàn)一個(gè)單例的 IOC 容器時(shí),我只需要新建一個(gè) Module 然后引入剛才的模塊并實(shí)現(xiàn) CicadaBeanFactory 接口即可。

當(dāng)然其中最重要的則是需要在 resources 目錄下新建一個(gè) META-INF/services/top.crossoverjie.cicada.base.bean.CicadaBeanFactory 文件,文件名必須得是我們之前定義接口的全限定名(SPI 規(guī)范)。

其中的內(nèi)容便是我們自己實(shí)現(xiàn)類的全限定名:

top.crossoverjie.cicada.bean.ioc.CicadaIoc

可以想象最終會(huì)通過這里的全限定名來反射創(chuàng)建對(duì)象。

只不過這個(gè)過程 Java 已經(jīng)提供 API 屏蔽掉了:

public static CicadaBeanFactory getCicadaBeanFactory() {
    ServiceLoader<CicadaBeanFactory> cicadaBeanFactories = ServiceLoader.load(CicadaBeanFactory.class);
    if (cicadaBeanFactories.iterator().hasNext()){
      return cicadaBeanFactories.iterator().next() ;
    }

    return new CicadaDefaultBean();
  }

當(dāng) classpath 中存在我們剛才的實(shí)現(xiàn)類(引入實(shí)現(xiàn)類的 jar 包),便可以通過 java.util.ServiceLoader 工具類來找到所有的實(shí)現(xiàn)類(可以有多個(gè)實(shí)現(xiàn)類同時(shí)存在,只不過通常我們只需要一個(gè))。

一些都準(zhǔn)備好之后,使用自然就非常簡單了。

<dependency>
    <groupId>top.crossoverjie.opensource</groupId>
    <artifactId>cicada-ioc</artifactId>
    <version>2.0.4</version>
  </dependency>

我們只需要引入這個(gè)依賴便能使用它的實(shí)現(xiàn),當(dāng)我們想換一種實(shí)現(xiàn)方式時(shí)只需要更換一個(gè)依賴即可。

這樣就做到了不修改一行代碼靈活的可拔插選擇 IOC 容器了。

SPI 的一些其他應(yīng)用

雖然平時(shí)并不會(huì)直接使用到 SPI 來實(shí)現(xiàn)業(yè)務(wù),但其實(shí)我們使用過的絕大多數(shù)框架都會(huì)提供 SPI 接口方便使用者擴(kuò)展自己的功能。

比如 Dubbo 中提供一系列的擴(kuò)展:

同類型的 RPC 框架 motan 中也提供了響應(yīng)的擴(kuò)展:

他們的使用方式都和 Java SPI 非常類似,只不過原理略有不同,同時(shí)也新增了一些功能。

比如 motan 的 spi 允許是否為單例等等。

再比如 MySQL 的驅(qū)動(dòng)包也是利用 SPI 來實(shí)現(xiàn)自己的連接邏輯。

總結(jié)

Java 自身的 SPI 其實(shí)也有點(diǎn)小毛病,比如:

遍歷加載所有實(shí)現(xiàn)類效率較低。當(dāng)多個(gè) ServiceLoader 同時(shí) load 時(shí)會(huì)有并發(fā)問題(雖然沒人這么干)。

最后總結(jié)一下,SPI 并不是某項(xiàng)高深的技術(shù),本質(zhì)就是面向接口編程,而面向接口本身在我們?nèi)粘i_發(fā)中也是必備技能,所以了解使用 SPI 也是很用處的。

本文所有源碼:

https://github.com/TogetherOS/cicada

到此這篇關(guān)于Java SPI 機(jī)制知識(shí)點(diǎn)總結(jié)的文章就介紹到這了,更多相關(guān)Java SPI 機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot使用Swagger生成多模塊的API文檔

    SpringBoot使用Swagger生成多模塊的API文檔

    這篇文章將以?Spring?Boot?多模塊項(xiàng)目為例,為大家詳細(xì)介紹一下如何使用?Swagger?生成多模塊的?API?文檔,感興趣的小伙伴可以了解一下
    2025-02-02
  • 深入講解Java?synchronized的核心原理

    深入講解Java?synchronized的核心原理

    這篇文章主要為大家詳細(xì)介紹了Java中synchronized的核心原理以及簡單的用法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-07-07
  • Java注釋代碼執(zhí)行方法解析

    Java注釋代碼執(zhí)行方法解析

    這篇文章主要介紹了Java注釋代碼執(zhí)行方法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • 一文搞懂Spring中@Autowired和@Resource的區(qū)別

    一文搞懂Spring中@Autowired和@Resource的區(qū)別

    @Autowired?和?@Resource?都是?Spring/Spring?Boot?項(xiàng)目中,用來進(jìn)行依賴注入的注解。它們都提供了將依賴對(duì)象注入到當(dāng)前對(duì)象的功能,但二者卻有眾多不同,并且這也是常見的面試題之一,所以我們今天就來盤它
    2022-08-08
  • Java初學(xué)者入門之繼承和多態(tài)

    Java初學(xué)者入門之繼承和多態(tài)

    Java 面向?qū)ο缶幊逃腥筇匦裕悍庋b、繼承、多態(tài),學(xué)好繼承和多態(tài)是面向?qū)ο箝_發(fā)語言中非常重要的一個(gè)環(huán)節(jié),這篇文章主要給大家介紹了關(guān)于Java初學(xué)者入門之繼承和多態(tài)的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • 探究springboot中的TomcatMetricsBinder

    探究springboot中的TomcatMetricsBinder

    springboot的TomcatMetricsBinder主要是接收ApplicationStartedEvent然后創(chuàng)建TomcatMetrics執(zhí)行bindTo進(jìn)行注冊(cè),TomcatMetrics主要注冊(cè)了globalRequest、servlet、cache、threadPool、session相關(guān)的指標(biāo),本文給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2023-11-11
  • Java Web 實(shí)現(xiàn)QQ登錄功能一個(gè)帳號(hào)同一時(shí)間只能一個(gè)人登錄

    Java Web 實(shí)現(xiàn)QQ登錄功能一個(gè)帳號(hào)同一時(shí)間只能一個(gè)人登錄

    對(duì)于一個(gè)帳號(hào)在同一時(shí)間只能一個(gè)人登錄,下文給大家介紹的非常詳細(xì),對(duì)java web qq 登錄功能感興趣的朋友一起看看吧
    2016-11-11
  • Maven之分析剔除無用的jar引用問題

    Maven之分析剔除無用的jar引用問題

    這篇文章主要介紹了Maven之分析剔除無用的jar引用問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Java基本數(shù)據(jù)類型之間的相互轉(zhuǎn)換詳解

    Java基本數(shù)據(jù)類型之間的相互轉(zhuǎn)換詳解

    這篇文章主要講解Java中基本數(shù)據(jù)類型的轉(zhuǎn)換,數(shù)據(jù)之間相互轉(zhuǎn)換是經(jīng)常會(huì)用到的基礎(chǔ)操作,文中講的很清晰,希望能給大家做一個(gè)參考。
    2022-05-05
  • Java判斷對(duì)象是否為空(包括null ,

    Java判斷對(duì)象是否為空(包括null ,"")的方法

    這篇文章主要介紹了Java判斷對(duì)象是否為空(包括null ,"")的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05

最新評(píng)論

本溪| 彭州市| 林芝县| 屯留县| 永川市| 龙海市| 九江县| 高雄市| 丁青县| 东辽县| 黄山市| 巴楚县| 琼海市| 章丘市| 墨竹工卡县| 隆德县| 辉南县| 新建县| 甘谷县| 东乌| 平凉市| 汶川县| 聂拉木县| 满洲里市| 垦利县| 南开区| 无锡市| 工布江达县| 南靖县| 天台县| 合江县| 宣城市| 吴川市| 晴隆县| 开远市| 德令哈市| 山阴县| 永寿县| 龙海市| 青海省| 奉新县|