成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

請問Dubbo的SPI機制是啥啊?

開發(fā) 架構(gòu)
Dubbo還有一個很大的優(yōu)點,就是采用的微內(nèi)核+SPI擴展設(shè)計,這又是什么呢,這個可以很好的支持一些有特殊需求的三方的接入,可以自定義擴展,自主定制二次開發(fā),良好的擴展性對于框架來說是很重要的。

[[423003]]

前言

之前大致的把Dubbo的運作流程簡單的分析了一遍了,Dubbo還有一個很大的優(yōu)點,就是采用的微內(nèi)核+SPI擴展設(shè)計。

這又是什么呢,這個可以很好的支持一些有特殊需求的三方的接入,可以自定義擴展,自主定制二次開發(fā),良好的擴展性對于框架來說是很重要的。

簡單了解下SPI,全稱為 Service Provider Interface,是一種服務(wù)發(fā)現(xiàn)機制。

它通過在ClassPath路徑下的META-INF/services文件夾查找文件,自動加載文件里所定義的類。這一機制為很多框架擴展提供了可能,比如在Dubbo、JDBC中都使用到了SPI機制。

舉個例子,比如你有個接口,現(xiàn)在這個接口有 3 個實現(xiàn)類,那么在系統(tǒng)運行的時候?qū)@個接口到底選擇哪個實現(xiàn)類呢?這就需要SPI了,需要根據(jù)指定的配置或者是默認的配置,去找到對應(yīng)的實現(xiàn)類加載進來,然后用這個實現(xiàn)類的實例對象。

Java中JDK自身實現(xiàn)了SPI機制,基于策略模式來實現(xiàn)動態(tài)加載的機制 。我們在程序只定義一個接口,具體的實現(xiàn)交個不同的服務(wù)提供者;在程序啟動的時候,讀取配置文件,由配置確定要調(diào)用哪一個實現(xiàn)。

但是呢,存在一定的缺點,比如不能按照需要加載,會一次性加載所有可用的擴展點,很多是不需要的,會浪費系統(tǒng)資源;不支持AOP和依賴注入,實現(xiàn)類的方式也不夠靈活,只能通過 Iterator 形式獲取。

你不夠強,或者說你做的不符合我的需求,我就替換你。

于是呢,dubbo重新實現(xiàn)了一套功能更強的 SPI 機制, 支持了AOP與依賴注入,并且 利用緩存提高加載實現(xiàn)類的性能,同時支持實現(xiàn)類的靈活獲取。

Java中的SPI

Java中JDK自身實現(xiàn)了SPI機制,基于策略模式來實現(xiàn)動態(tài)加載的機制 。我們在程序只定義一個接口,具體的實現(xiàn)交個不同的服務(wù)提供者;在程序啟動的時候,讀取配置文件,由配置確定要調(diào)用哪一個實現(xiàn)。

首先,我們需要定義一個接口,SPIService。

  1. public interface SPIService { 
  2.     void execute(); 

然后,定義兩個實現(xiàn)類,沒別的意思,只輸入一句話。‍

  1. public class SpiImpl1 implements SPIService{ 
  2.     public void execute() { 
  3.         System.out.println("SpiImpl1.execute()"); 
  4.     } 
  5.  
  6. public class SpiImpl2 implements SPIService{ 
  7.     public void execute() { 
  8.         System.out.println("SpiImpl2.execute()"); 
  9.     } 

最后呢,要在ClassPath路徑下配置添加一個文件。文件名字是接口的全限定類名,內(nèi)容是實現(xiàn)類的全限定類名,多個實現(xiàn)類用換行符分隔。內(nèi)容就是實現(xiàn)類的全限定類名:

  1. com.tech.dayu.spi.SpiImpl1 
  2. com.tech.dayu.spi.SpiImpl2 

測試

  1. public class Test { 
  2.     public static void main(String[] args) {     
  3.         Iterator<SPIService> providers = Service.providers(SPIService.class); 
  4.         ServiceLoader<SPIService> load = ServiceLoader.load(SPIService.class); 
  5.  
  6.         while(providers.hasNext()) { 
  7.             SPIService ser = providers.next(); 
  8.             ser.execute(); 
  9.         } 
  10.         System.out.println("###################"); 
  11.         Iterator<SPIService> iterator = load.iterator(); 
  12.         while(iterator.hasNext()) { 
  13.             SPIService ser = iterator.next(); 
  14.             ser.execute(); 
  15.         } 
  16.     } 

兩種方式的輸出結(jié)果是一致的:

  1. SpiImpl1.execute() 
  2. SpiImpl2.execute() 
  3. -------------------------------- 
  4. SpiImpl1.execute() 
  5. SpiImpl2.execute() 

我們來看下源碼,位于java.util包下。我們就以ServiceLoader.load為例,通過源碼看看它里面到底怎么做的。

ServiceLoader.load()其實就是 Java SPI 入口

看到最后調(diào)用的是reload,最后生效的是在這個LazyIterator的內(nèi)部,等同于是一個迭代器的遍歷,遍歷相應(yīng)的文件中的service的實現(xiàn)類,就是我們上面命名的那些。

這里無論是if還是else最后調(diào)用的都是nextService()方法,點進去看

可以看到無非就是通過名字獲取到文件路徑,獲取全限定名來加載類,并且創(chuàng)建其實例放入到相應(yīng)的緩存之后并且返回實例,這大體就是整個的實現(xiàn)邏輯,應(yīng)該不難吧,咱們自己來實現(xiàn)個這個應(yīng)該也是分分鐘的事

好了,Java的SPI源碼分析的差不多了,問題也隨之而來,比如不能按照需要加載,會一次性加載所有可用的擴展點,很多是不需要的,會浪費系統(tǒng)資源;不支持AOP和依賴注入,實現(xiàn)類的方式也不夠靈活,只能通過 Iterator 形式獲取

接下來咱們來分析Dubbo的SPI

Dubbo中的SPI

Dubbo 并未使用 Java SPI,而是重新實現(xiàn)了一套功能更強的 SPI 機制。

Dubbo SPI 的相關(guān)邏輯被封裝在了 ExtensionLoader 類中,通過 ExtensionLoader,我們可以加載指定的實現(xiàn)類。Dubbo SPI 所需的配置文件需放置在 META-INF/dubbo 路徑下。

Dubbo要判斷一下,在系統(tǒng)運行時,應(yīng)該選用這個Protocol接口的哪個實現(xiàn)類。它會去找一個你配置的Protocol,將你配置的Protocol實現(xiàn)類,加載進JVM,將其實例化,微內(nèi)核,可插拔,大量的組件,Protocol負責(zé)RPC調(diào)用的東西,你可以實現(xiàn)自己的RPC調(diào)用組件,實現(xiàn)Protocol接口,給自己的一個實現(xiàn)類就可以啦

Dubbo里很多都是保留一個接口和多個實現(xiàn),然后在系統(tǒng)運行的時候動態(tài)根據(jù)配置去找到對應(yīng)的實現(xiàn)類。如果你沒配置,那就走默認的實現(xiàn)就可以啦

我們隨便來看一下其中的

并且 Dubbo SPI 除了可以按需加載實現(xiàn)類之外,增加了 IOC 和 AOP 的特性,還有個自適應(yīng)擴展機制。

我們先來看一下 Dubbo 對配置文件目錄的約定,不同于 Java SPI ,Dubbo 分為了三類目錄。

  • META-INF/services/ 目錄:該目錄下的 SPI 配置文件是為了用來兼容 Java SPI 。
  • META-INF/dubbo/ 目錄:該目錄存放用戶自定義的 SPI 配置文件。
  • META-INF/dubbo/internal/ 目錄:該目錄存放 Dubbo 內(nèi)部使用的 SPI 配置文件。

接下來我們來看Dubbo的SPI的源碼

在Dubbo中ExtensionLoader類似 Java SPI 中 ServiceLoader 的存在。大致流程就是先通過接口類找到ExtensionLoader ,然后再通過 ExtensionLoader.getExtension(name) 得到指定名字的實現(xiàn)類實例。

其實也是很簡單的,就是通過一頓判斷然后在緩存中檢查是否存在這個類型的ExtensionLoader ,沒有的話就新建一個放進去緩存,最后返回接口類的對應(yīng)的ExtensionLoader

getExtension() 方法,從現(xiàn)象我們可以知道這個方法就是從類對應(yīng)的 ExtensionLoader 中通過名字找到實例化完的實現(xiàn)類

內(nèi)部的createExtension()方法,我就不截圖了,比較長,就是先找實現(xiàn)類,判斷是否有該類的緩存,沒有的話就通過反射新建一個實例對象,然后放進去

到這里其實就差不多了分析的,拿到實例對然后就可以執(zhí)行了

Dubbo的SPI主要就是為了增加框架的可拓展性,可以在其基礎(chǔ)上進行二次開發(fā),還有一個更重要的點就是不會像Java的SPI一樣直接全部加載,那樣可能會造成大量的資源浪費的,甚至可能還會做無用功

【編輯推薦】

 

責(zé)任編輯:姜華 來源: 大魚仙人
相關(guān)推薦

2024-10-29 08:34:55

SPI機制接口

2025-05-08 03:25:00

DubboSPI機制

2020-12-14 11:35:22

SPI Java機制

2025-05-20 05:53:07

DubboSPI機制

2025-03-04 09:02:25

JavaSPI機制

2020-06-30 15:35:36

JavaSPI代碼

2011-11-30 14:35:19

JavaSPI

2024-01-15 08:25:53

SPI機制JavaDubbo

2023-12-11 07:21:12

SPI機制插件

2018-07-06 15:30:14

DubboSPIJDK

2022-08-17 08:17:01

SPI機制接口

2022-05-06 08:26:32

JavaSPI機制

2021-08-28 09:06:11

Dubbo架構(gòu)服務(wù)

2020-08-18 08:04:16

DubboSPI框架

2023-03-13 22:09:59

JavaSpring機制

2025-03-27 02:00:00

SPIJava接口

2023-08-28 10:42:25

DubboSPIJava

2021-05-30 07:54:24

SPI機制場景

2017-05-14 16:34:07

語言PLSQL

2020-11-20 07:51:02

JavaSPI機制
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 黄网站涩免费蜜桃网站 | 欧美日韩中文字幕在线播放 | 日韩免费一区 | www.中文字幕.com | 91久久久久久久久 | 911影院 | 精品无码久久久久久久动漫 | 亚洲精品二区 | 午夜天堂精品久久久久 | 国产精久久久 | 欧美久久视频 | 麻豆精品国产91久久久久久 | 亚洲一区二区三区四区五区午夜 | 5060网一级毛片 | 日韩精品一区二区三区视频播放 | 国产一区二区三区免费 | 一级片免费视频 | 午夜精品网站 | 国产欧美在线一区二区 | 日本一本在线 | 精品9999| 高清一区二区三区 | 毛片综合| 久久久久久国产精品免费免费 | 亚洲视频免费在线观看 | 久久午夜精品福利一区二区 | 99久久精品免费看国产高清 | 99在线国产| 久草久草久草 | a在线免费观看视频 | 亚洲精品在线看 | 中文字幕日韩专区 | 成年人在线 | 国产激情视频网站 | 欧美美女爱爱视频 | 特黄毛片 | 国产一区二区三区在线 | 国产精品a一区二区三区网址 | 男人天堂免费在线 | 免费高潮视频95在线观看网站 | 成人午夜免费福利视频 |