Java服務(wù)提供框架

本文探討Effective Java E3 CH2中提到的服務(wù)提供框架,引申點(diǎn)有JDBC實(shí)現(xiàn)、SPI機(jī)制等。

原文

There are three essential components in a service provider framework: a service interface, which represents an implementation; a provider registration API, which providers use to register implementations; and a service access API, which clients use to obtain instances of the service. The service access API may allow clients to specify criteria for choosing an implementation. In the absence of such criteria, the API returns an instance of a default implementation, or allows the client to cycle through all available implementations. The service access API is the flexible static factory that forms the basis of the service provider framework.
An optional fourth component of a service provider framework is a service provider interface, which describes a factory object that produce instances of the service interface. In the absence of a service provider interface, implementations must be instantiated reflectively (Item 65). In the case of JDBC, Connection plays the part of the service interface, DriverManager.registerDriver is the provider registration API, DriverManager.getConnection is the service access API, and Driver is the service provider interface.

解釋及思考

服務(wù)提供框架的三個(gè)必要組成部分: 服務(wù)接口(Service Interface)、服務(wù)提供者注冊(cè)API( Provider Registration API)、服務(wù)獲取API(Service Access API)
客戶端通過調(diào)用Service Interface實(shí)現(xiàn)功能調(diào)用,服務(wù)獲取API幫助客戶端獲取服務(wù)接口實(shí)例,服務(wù)獲取API通常為靜態(tài)方法,客戶端可以自由選擇不同的服務(wù)實(shí)現(xiàn)。
Provider Registration API注冊(cè)Service Implementation(什么是注冊(cè))
還有一個(gè)可選擇的組成部分:服務(wù)提供接口(Service Provider Interface,SPI)
在日常使用中,SPI提及頻率也很高,在沒有SPI的情況下,service implementation必須通過反射的方式實(shí)例化(why)。

回顧JDBC的使用方法:

   static{
         try {
             //1.加載驅(qū)動(dòng)程序
             Class.forName("com.mysql.jdbc.Driver");
             //2.獲得數(shù)據(jù)庫(kù)的連接
             conn = DriverManager.getConnection(URL, NAME, PASSWORD);
         } catch (ClassNotFoundException e) {
             e.printStackTrace();
         } catch (SQLException e) {
             e.printStackTrace();
         }
     }

客戶端程序通過Connection對(duì)象操作數(shù)據(jù)庫(kù),則Connection相當(dāng)于service API, DriverManager.getConnection相當(dāng)于Service Access API. Class.forName("com.mysql.jdbc.Driver") 這個(gè)步驟相當(dāng)于Provider注冊(cè),加載mysql驅(qū)動(dòng)之后provider提供的connection實(shí)現(xiàn)才是客戶端所需的實(shí)例; Class.forName("com.mysql.jdbc.Driver")是將Driver類加載到內(nèi)存中,加載至內(nèi)存中以后Driver會(huì)調(diào)用DriverMananger的rigisteDriver方法。
考慮JDBC的實(shí)例,總結(jié)service interface, provider registration API, Service Access API三者之間的關(guān)系和簡(jiǎn)單敘述為:

  • provider registation API: 調(diào)用者告訴提供者,provider做一些服務(wù)準(zhǔn)備工作(多為provider的必要類加載)。
  • service interface: 調(diào)用者直接調(diào)用用以獲取提供者提供的功能
  • service access API: Service Interface有不同的實(shí)現(xiàn),調(diào)用者通過service access API獲取所需的interface實(shí)例。
    三者關(guān)系如圖所示:


    服務(wù)提供框架結(jié)構(gòu)圖

現(xiàn)在可以繼續(xù)思考一個(gè)問題,在缺席SPI的情況下,provider是如何注冊(cè)的?原文中有一段說(shuō):

An optional fourth component of a service provider framework is a service provider interface, which describes a factory object that produce instances of the service interface. In the absence of a service provider interface, implementations must be instantiated reflectively (Item 65)

原文中說(shuō),在沒有SPI的情況下,provider只能通過反射的方式實(shí)例化service interface, Service Interface實(shí)現(xiàn)為新的實(shí)例,在運(yùn)行過程中初始化新的實(shí)例只能通過反射的方法。在JDBC API實(shí)現(xiàn)中,注冊(cè)過程使用反射獲取新的Diver實(shí)例,service interface通過調(diào)用Driver實(shí)例獲取。
SPI是什么,SPI又是如何通過接口的方法避免使用反射的?SPI不與使用反射方法沖突,Java Service Loader中同樣應(yīng)用了反射。原文定義SPI為提供service interface實(shí)例的靜態(tài)工廠。
目前對(duì)SPI的理解為:提供caller調(diào)用provider的接口,用于provider注冊(cè)。

擴(kuò)展

上述模式稱之為service provider framework pattern(服務(wù)提供者模式),服務(wù)提供者模式的變體如
橋接模式,依賴注入框架可以視為service provider。

參考

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,864評(píng)論 0 10
  • 文章作者:Tyan博客:noahsnail.com Chapter 2 Creating and Destroyi...
    SnailTyan閱讀 724評(píng)論 0 1
  • =========================================================...
    lavor閱讀 3,649評(píng)論 0 5
  • 第1條:考慮靜態(tài)工廠方法代替構(gòu)造器 ??對(duì)于類而言,為了讓客戶端獲取它自身的一個(gè)實(shí)例,最常用的方法就是提供一個(gè)公有...
    xymlhn閱讀 270評(píng)論 0 0
  • pyspark.sql模塊 模塊上下文 Spark SQL和DataFrames的重要類: pyspark.sql...
    mpro閱讀 9,920評(píng)論 0 13

友情鏈接更多精彩內(nèi)容