0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

什么是SPI機制

科技綠洲 ? 來源:Java技術指北 ? 作者:Java技術指北 ? 2023-10-08 15:03 ? 次閱讀

1、前言

在之前的JVM 分析系列之類加載提到過 Java SPI 機制,主要是類加載器反雙親委派的實現(第三方包不在指定jdk路徑,一般類加載器無法加載,需要特殊的ContextClassLoader加載以便使用)。本次將對 SPI機制進行詳解,并結合案例介紹其在實際場景中具體使用。

2、什么是SPI機制?

  • SPI(全稱:Service Provider Interface),是jdk內置的一種服務提供發(fā)現接口機制,旨在由第三方服務實現或擴展為組件,方便開發(fā)人員快速集成指定擴展組件滿足指定的需求。這對于應用或平臺擴展來說,無疑是一種成本較低、動態(tài)靈活的方案。
  • SPI機制調度過程(業(yè)務調用方可根據加載的擴展實現類實現功能)
  • 調用流程
    圖片

3、實現方式及使用場景

鑒于目前實際項目涉及范圍,總結出的常見應用場景。

3.1 接口權限定文件名方式

  • 即在resource文件下創(chuàng)建META/services/目錄,并在此目錄下新建文件,文件名稱為接口類權限定文件名,如 com.lgy.spidemo.serviceway.SpiService。(不好理解就是接口類的package地址 + 接口類名)

使用場景一:

  • 場景描述:不同部門類型的員工需要從不同的考勤應用獲取出勤信息,如職能部門僅拉取釘釘考勤,業(yè)務部門需要拉取釘釘考勤的基礎上再結合自研考勤模塊數據匯總出勤結果。
  • 實現方式:抽象通用拉取考勤接口,定義不同部門人員考勤統(tǒng)計實現類。
  • 直接上代碼:
  • 通用接口:
package com.lgy.spidemo.serviceway;

 /**
  * @description: 考勤接口
  **/
 public interface AttendanceService {
  void pullAttendanceInfos();
 }
  • 職能部門考勤實現類
/**
  * @description: 職能部門考勤實現
  **/
 public class FunctionAttendanceServiceImpl implements AttendanceService  {
  @Override
  public void pullAttendanceInfos() {
   System.out.println(" FunctionAttendanceService implements ...");
   // 邏輯忽略
  }
 }
  • 銷售部門考勤實現
/**
  * @description: 銷售部門考勤實現
  **/
 public class SaleAttendanceServiceImpl implements AttendanceService  {
  @Override
  public void pullAttendanceInfos() {
   System.out.println(" SaleAttendanceService implements ...");
   // 邏輯忽略
  }
 }
  • 測試類
/**
  * 1、項目的srcmainresources下創(chuàng)建META-INFservices目錄
  * 2、META-INFservices的目錄下再增加一個配置文件,這個文件必須以接口的全限定類名保持一致 (com.lgy.spidemo.service.SpiService)
  * 3、在配置文件中寫入具體實現類的全限定類名,如有多個便換行寫入 com.lgy.spidemo.service.impl.SaleAttendanceServiceImpl
 com.lgy.spidemo.service.impl.FunctionAttendanceServiceImpl
  **/
 public class AttendanceServiceTest {
  public static void main(String[] args) {
   ServiceLoader< AttendanceService > services =
      ServiceLoader.load(AttendanceService.class);
   // 省略判斷人員部門類型邏輯
   // 測試輸出結果,展示實現接口已加載
   for (AttendanceService service : services) {
    service.pullAttendanceInfos();
   }
  }
 }
  • 測試結果如下
// 兩個實現類均被加載成功,在實際使用時,可根據需要去調用不同的實現。
     FunctionAttendanceService implements ...
     SaleAttendanceService implements ....
  • 實現類不要標注任何注解,不然Spring在初始化過程中掃描并加載,無法測試。

結合場景一分析:

  • 此場景可以通過自定義實現類的方式滿足業(yè)務需求(不同部門的考勤規(guī)則),有助于業(yè)務實現快速迭代,同時也提升了服務架構的可拓展性。
  • 考慮公司組織架構比較復雜,部門職責分的比較細,后續(xù)擴展幾率比較大,比如職能部門行政類和運營類標準細分,很可能會增加除了考勤之外的各種考核指標等,借鑒此方案可能簡單實現并比較方便集成,使得業(yè)務間減少依賴,實現解耦的設計模式,因此個人是比較偏向用此方案。
  • 其它應用:如項目中常用的日志也是采用SPI機制,常見的common-logging的LogFatory就是標準SPI接口,有興趣的可以自行研究。

3.2 spring.factories方式

  • 和上面一樣,需要在resource文件下創(chuàng)建META/services/目錄,并在此目錄下新建文件,區(qū)別在于文件名為 spring.factories 。

使用場景二

  • 場景描述:針對于不同的開發(fā)端使用習慣展示不同的接口文檔,比如APP端習慣于Swagger,JAVA端喜歡dateway風格,就在不同實例展示不同接口文檔。此場景是我臆想出來。
  • 實現方式:構建兩種版本的jar包,比如 1.0.0-swagger 、2.0.0-dataway,再對應的包內配置spring.factories內的config配置類。
  • 代碼如下:
package com.lgy.spidemo.factoriesway;

 import org.springframework.boot.autoconfigure.AutoConfigurationImportEvent;
 import org.springframework.boot.autoconfigure.AutoConfigurationImportListener;

 /**
  * @description: 自動配置swagger
  **/
 public class SwaggetAutoConfiguration {
  public SwaggetAutoConfiguration() {
   System.out.println(" SwaggetAutoConfiguration init ...");
  }
  // 配置內容省略
 }

 /**
  * @description: 自動配置dataway
  **/
 public class DataWayAutoConfiguration {
  public DataWayAutoConfiguration() {
   System.out.println(" DataWayAutoConfiguration init ...");
  }
  // 配置內容省略
 }

 /**
 * resource/META-INFO/spring.factories 文件內容 *
 * org.springframework.boot.autoconfigure.EnableAutoConfiguration=
   com.lgy.spidemo.factoriesway.SwaggetAutoConfiguration
 * 輸出結果:SwaggetAutoConfiguration init ...
 **/
  • 根據spring.factories內配置的類,在springboot啟動初始化過程中會自動加載對應的配置,實現所需的接口文檔。

結合場景二分析:

  • spring.factories實現機制與上述方式一致,只是實現方式不同,本質目的是通過抽象化類的方式,實現解耦,最終便于擴展
  • 其它使用場景:如spring-boot-autoconfigure-x.x.x.RELEASE.jar,就是通過此方式完成初始化加載。

4、總結

  • 本次講解的兩種方式均是基于SPI機制,可見是多么受開發(fā)追捧。當然,還有很多種實現方式,我個人覺得最主要的還是能夠在自己的掌控范圍內去使用,畢竟有問題可以通過自己的學習理解去解決。
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 接口
    +關注

    關注

    33

    文章

    8598

    瀏覽量

    151157
  • SPI
    SPI
    +關注

    關注

    17

    文章

    1706

    瀏覽量

    91581
  • 代碼
    +關注

    關注

    30

    文章

    4788

    瀏覽量

    68612
  • Package
    +關注

    關注

    0

    文章

    26

    瀏覽量

    10497
  • spring
    +關注

    關注

    0

    文章

    340

    瀏覽量

    14343
收藏 人收藏

    評論

    相關推薦

    關于SPI通訊的精講 SPI協(xié)議的特點和工作機制

    1、SPI協(xié)議簡介 1.1 SPI協(xié)議概括 SPI,是英語Serial Peripheral interface的縮寫,顧名思義就是串行外圍設備接口。是Motorola首先在其MC68HCXX系列
    的頭像 發(fā)表于 05-08 19:55 ?9843次閱讀
    關于<b class='flag-5'>SPI</b>通訊的精講 <b class='flag-5'>SPI</b>協(xié)議的特點和工作<b class='flag-5'>機制</b>

    SPI總線學習筆記

    SPI是一種全雙工的串行通信總線,最早由Motorola提出,雖然應用廣泛,但沒有一個統(tǒng)一的總線標準。相較于IIC總線,SPI具有通信速度快、協(xié)議靈活、無復雜的總線仲裁機制、支持中斷等優(yōu)點,但缺點也
    發(fā)表于 09-20 15:17 ?1084次閱讀
    <b class='flag-5'>SPI</b>總線學習筆記

    聊聊Dubbo - Dubbo可擴展機制實戰(zhàn)

    OSGI容器Dubbo作為一個框架,不希望強依賴其他的IoC容器,比如Spring,Guice。OSGI也是一個很重的實現,不適合Dubbo。最終Dubbo的實現參考了Java原生的SPI機制,但對其
    發(fā)表于 06-04 17:33

    SPI是什么?SPI的特點有哪些呢

    SPI是什么?SPI的特點有哪些呢?STM32的SPI工作機制有哪些呢?
    發(fā)表于 11-03 07:14

    RT_SFUD_SPI_MAX_HZ到底是什么作用機制呢?

    設定會導致spi clk 的波形畸變。設定 13mhz時波形:示波器顯示頻率 25mhz設定 13mhz時波形:示波器顯示頻率 50mhz疑問:1:RT_SFUD_SPI_MAX_HZ 到底是什么作用機制2:
    發(fā)表于 04-14 10:08

    SPI模式下MMC卡的讀寫機制

    SPI模式下MMC卡的讀寫機制  多媒體卡MMC(MultiMedia Card)是由美國SanDisk公司和德國Simens公司于1997年共同開發(fā)的一種多功能Flash存儲設備。基于ARM7芯
    發(fā)表于 03-29 15:13 ?1212次閱讀
    <b class='flag-5'>SPI</b>模式下MMC卡的讀寫<b class='flag-5'>機制</b>

    SPI總線協(xié)議的工作機制解析

    SPI,串行外圍設備接口,是Motorola公司推出的一種同步串行接口技術.SPI總線在物理上是通過接在外圍設備微控制器(PICmicro)上面的微處理控制單元(MCU)上叫作同步串行端口
    發(fā)表于 08-25 17:38 ?1408次閱讀
    <b class='flag-5'>SPI</b>總線協(xié)議的工作<b class='flag-5'>機制</b>解析

    基于SPI協(xié)議的SD卡讀寫機制與實現方法

    基于SPI協(xié)議的SD卡讀寫機制與實現方法。
    發(fā)表于 03-25 11:21 ?27次下載
    基于<b class='flag-5'>SPI</b>協(xié)議的SD卡讀寫<b class='flag-5'>機制</b>與實現方法

    SPI通信簡介

    目錄(?)[-]SPI簡介SPI特點1采用主-從模式Master-Slave 的控制方式2采用同步方式Synchronous傳輸數據3數據交換Data Exchanges4 SPI有四種傳輸模式5
    發(fā)表于 12-22 19:14 ?9次下載
    <b class='flag-5'>SPI</b>通信簡介

    源碼級深度理解Java SPI

    SPI 配置:Java SPI 機制約定的配置文件,提供查找服務實現類的邏輯。配置文件必須置于 META-INF/services 目錄中,并且,文件名應與服務提供者接口的完全限定名保持一致。文件中的每一行都有一個實現服務類的詳
    的頭像 發(fā)表于 11-15 11:38 ?667次閱讀

    JDK內置的一種服務SPI機制

    SPI(Service Provider Interface)是JDK內置的一種服務提供發(fā)現機制,可以用來啟用框架擴展和替換組件,主要用于框架中開發(fā),例如Dubbo、Spring
    的頭像 發(fā)表于 02-15 09:15 ?794次閱讀

    基于spring的SPI擴展機制是如何實現的?

    基本上,你一說是基于 spring 的 SPI 擴展機制,再把spring.factories文件和EnableAutoConfiguration提一下,那么這個問題就答的八九不離十了。
    的頭像 發(fā)表于 03-07 09:17 ?1054次閱讀

    可插拔組件設計機制SPI介紹

    SPI 的全稱是 Service Provider Interface, 即提供服務接口;是一種服務發(fā)現機制,SPI 的本質是將接口實現類的全限定名配置在文件中,并由服務加載器讀取配置文件,加載實現類。
    的頭像 發(fā)表于 03-23 09:20 ?1165次閱讀

    Java、Spring、Dubbo三者SPI機制的原理和區(qū)別

    其實我之前寫過一篇類似的文章,但是這篇文章主要是剖析dubbo的SPI機制的源碼,中間只是簡單地介紹了一下Java、Spring的SPI機制,并沒有進行深入,所以本篇就來深入聊一聊這三
    的頭像 發(fā)表于 06-05 15:21 ?1039次閱讀
    Java、Spring、Dubbo三者<b class='flag-5'>SPI</b><b class='flag-5'>機制</b>的原理和區(qū)別

    SPI傳輸原理 SPI傳輸機制

    SPI 傳輸機制 從圖可以看出,主機和從機都有一個串行移位寄存器,主機通過向它的 SPI 串行寄存器寫入一個字節(jié)來發(fā)起一次傳輸。寄存器通過 MOSI 信號線將字節(jié)傳送給從機,從機也將自己的移位寄存器
    的頭像 發(fā)表于 07-27 10:43 ?2587次閱讀
    <b class='flag-5'>SPI</b>傳輸原理 <b class='flag-5'>SPI</b>傳輸<b class='flag-5'>機制</b>