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

Java SPI簡單應(yīng)用案例詳解

 更新時(shí)間:2021年08月31日 15:22:41   作者:nimo10050  
這篇文章主要介紹了Java SPI簡單應(yīng)用案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下

開篇

本文主要談一下 Java SPI(Service Provider Interface) ,因?yàn)樽罱诳?Dubbo 的相關(guān)內(nèi)容,其中涉及到了 一個(gè)概念- Dubbo SPI, 最后又牽扯出來了 JAVA SPI, 所以先從 Java SPI 開整。

正文

平常學(xué)習(xí)一個(gè)知識(shí)點(diǎn),我們的常規(guī)做法是:

  • 是什么
  • 有什么用
  • 怎么用

這次我們倒著做,先不談什么是 SPI 及其作用,來看下如何使用。

使用

1. 創(chuàng)建一個(gè) maven 工程

在這里插入圖片描述

2. 創(chuàng)建一個(gè)接口類以及實(shí)現(xiàn)類

// 接口
public interface HelloService {

    void sayHello();

}

// 實(shí)現(xiàn)類 1
public class HelloServiceImpl1 implements HelloService {
    @Override
    public void sayHello() {
        System.out.println("hello impl1");
    }
}

// 實(shí)現(xiàn)類 2
public class HelloServiceImpl2 implements HelloService {
    @Override
    public void sayHello() {
        System.out.println("hello impl2");
    }
}

3. 創(chuàng)建一個(gè) META-INF/services 文件夾,并添加一個(gè)文件

在 classpath 下面創(chuàng)建一個(gè)META-INF/services目錄,再在下面創(chuàng)建一個(gè)
以接口類全路徑名 命名的文件
即:com.nimo.spidemo.service.HelloService

4. 在第三步創(chuàng)建的文件中寫入如下內(nèi)容

寫入兩個(gè)實(shí)現(xiàn)類的全路徑名

com.nimo.spidemo.service.impl.HelloServiceImpl1
com.nimo.spidemo.service.impl.HelloServiceImpl2

5. 啟動(dòng)函數(shù)

public class App {

    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        // 方式 一
        Iterator<HelloService> providers = Service.providers(HelloService.class);
        while(providers.hasNext()) {
            HelloService ser = providers.next();
            ser.sayHello();
        }

        System.out.println("-----------------分割線---------------");
		// 方式 二
        ServiceLoader<HelloService> load = ServiceLoader.load(HelloService.class);
        Iterator<HelloService> iterator = load.iterator();
        while(iterator.hasNext()) {
            HelloService ser = iterator.next();
            ser.sayHello();
        }
    }

}

運(yùn)行結(jié)果如下:

hello impl1

hello impl2

-----------------分割線---------------

hello impl1

hello impl2

使用要素

針對上面的 demo,可以看出使用 Java SPI 的幾個(gè)關(guān)鍵要素:

  1. 接口類,比如 HelloService
  2. 對應(yīng)接口的實(shí)現(xiàn)類
    實(shí)現(xiàn)類必須攜帶一個(gè)不帶參數(shù)的構(gòu)造方法
  3. 文件夾 META-INF/services
    放置 classpath 目錄下
  4. 以“接口全限定名”命名的文件
  5. 文件內(nèi)容為接口實(shí)現(xiàn)類的全路徑

主程序通過java.util.ServiceLoder掃描META-INF/services下的配置文件,然后會(huì)找到實(shí)現(xiàn)類的全限定名,最后把類加載到JVM;

SPI 的作用

從上面的 demo 中可以看到,Java SPI 就是把某個(gè)接口的 指定實(shí)現(xiàn)類 (通過在指定文件配置的方式)給實(shí)例化出來了。

準(zhǔn)確+官方的說:

SPI 是一種將服務(wù)接口與服務(wù)實(shí)現(xiàn)分離以達(dá)到解耦、大大提升了程序可擴(kuò)展性的機(jī)制。引入服務(wù)提供者就是引入了 spi 接口的實(shí)現(xiàn)者,通過本地的注冊發(fā)現(xiàn)獲取到具體的實(shí)現(xiàn)類,輕松可插拔。

~~~ 如果還是不懂就接著往下看⬇️

SPI 的應(yīng)用場景

一個(gè)典型的案例就是 jdbc 。

數(shù)據(jù)庫各大廠商(如Mysql、Oracle)會(huì)根據(jù)一個(gè)統(tǒng)一的接口規(guī)范( java.sql.Driver )開發(fā)各自的驅(qū)動(dòng)實(shí)現(xiàn)邏輯。
客戶端使用 jdbc 時(shí)不需要去改變代碼,直接引入不同的 spi 接口服務(wù)即可。
例如 :
Mysql 是 com.mysql.jdbc.Drive
Oracle 是 oracle.jdbc.driver.OracleDriver

一段熟悉的代碼:

使用操作 mysql 數(shù)據(jù)庫的前置工作:

 //1.加載驅(qū)動(dòng)程序
Class.forName("com.mysql.jdbc.Driver");
//2. 獲得數(shù)據(jù)庫連接
Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);

當(dāng)我們需要切到 oracle 數(shù)據(jù)庫時(shí),更改驅(qū)動(dòng)為 oracle.jdbc.driver.OracleDriver, 最后修改連接信息【用戶名,密碼等】即可。

總結(jié)

Java SPI 是一種服務(wù)發(fā)現(xiàn)機(jī)制。它通過在 classPath 路徑下的 META-INF/services 文件夾查找文件,自動(dòng)加載文件里所定義的類。

它的核心關(guān)鍵作用就是 擴(kuò)展。

其他應(yīng)用場景:

  • 日志門面接口實(shí)現(xiàn)類加載
    SLF4J加載不同提供商的日志實(shí)現(xiàn)類
  • Spring
    Spring中大量使用了 SPI,比如:對 servlet3.0 規(guī)范 ServletContainerInitializer 的實(shí)現(xiàn)、自動(dòng)類型轉(zhuǎn)換Type Conversion SPI(Converter SPI、Formatter SPI)等
  • Dubbo
    Dubbo中也大量使用SPI的方式實(shí)現(xiàn)框架的擴(kuò)展, 不過它對Java提供的原生SPI做了封裝,允許用戶擴(kuò)展實(shí)現(xiàn)Filter接口

其中 Dubbo 中的 SPI 是接下來研究的重點(diǎn)。

到此這篇關(guān)于Java SPI簡單應(yīng)用案例詳解的文章就介紹到這了,更多相關(guān)Java SPI簡單應(yīng)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

唐海县| 手游| 黑水县| 商丘市| 朝阳市| 英吉沙县| 晋中市| 外汇| 新竹县| 吴堡县| 鹤壁市| 德州市| 保亭| 响水县| 肇东市| 贞丰县| 镇江市| 余江县| 乌鲁木齐县| 资兴市| 临清市| 上思县| 古丈县| 汤阴县| 土默特右旗| 丽江市| 上栗县| 垣曲县| 托克托县| 广德县| 邵武市| 龙井市| 汝州市| 全南县| 沙田区| 利川市| 乡宁县| 额济纳旗| 始兴县| 锦州市| 华宁县|