1. 程式人生 > 實用技巧 >java列舉型別 enum基本用法

java列舉型別 enum基本用法

SPI

SPI 全稱為 Service Provider Interface,是一種服務發現機制。

API:給消費者呼叫。SPI:給服務者提供介面,使用者可以自定義類實現介面。類似於留了個外掛槽,使用者可以自定義外掛使用。

SPI:破壞了雙親委派機制。例如:利用spi載入jdbc的java.sql.Driver,保證各個sql廠家實現自己的類。SLFJ等,相容各種日誌。

Bootstrap Classloader(只拿些rt.jar下的Stirng,Math等類)載入器拿到了Application ClassLoader載入器應該載入的類,就打破了雙親委派模型。(原本先讓父類進行載入,父類本來也沒有,才能被子類載入,現在通過SPI,直接在Bootstrap Classloader載入到JVM)

(先讓父載入器載入,然後字載入器載入。)

工作機制:建立流程

public interface Robot {
    void sayHello();
}

接下來定義兩個實現類,分別為 OptimusPrime 和 Bumblebee。

public class OptimusPrime implements Robot {
    
    @Override
    public void sayHello() {
        System.out.println("Hello, I am Optimus Prime.");
    }
}

public class Bumblebee implements Robot {

    @Override
    public void sayHello() {
        System.out.println("Hello, I am Bumblebee.");
    }
}

接下來 META-INF/services 資料夾下建立一個檔案,名稱為 Robot 的全限定名 org.apache.spi.Robot。檔案內容為實現類的全限定的類名,如下:

org.apache.spi.OptimusPrime
org.apache.spi.Bumblebee

做好所需的準備工作,接下來編寫程式碼進行測試。

public class JavaSPITest {

    @Test
    public void sayHello() throws Exception {
        ServiceLoader<Robot> serviceLoader = ServiceLoader.load(Robot.class);//相當於獲取到所有實現介面的類
        System.out.println("Java SPI");
        serviceLoader.forEach(Robot::sayHello);
    }
}

最後來看一下測試結果,如下:

從測試結果可以看出,我們的兩個實現類被成功的載入,並輸出了相應的內容。關於 Java SPI 的演示先到這裡,接下來演示 Dubbo SPI。

例子:jdbc的實現,mysql包下會配置一個檔案,包含需要SPI載入的類。

DriverManager.getcollection(url,user,password);

可以看到DriverManager在初始化時會使用ServiceLoader來載入java.sql.Driver的實現類。(載入驅動不應該是Class.forName嗎?)

確實JDBC驅動的載入是在Class.forName這一步完成的,但是後面的jdbc版本也支援SPI載入。(即使不寫Class.forName也能載入成功)

(判斷邏輯:如果Class.forName載入了資料庫驅動,則不適用SPI載入,否則選擇SPI進行載入。根據url的不同載入不同的驅動)

這個自動載入採用的技術叫做SPI,資料庫驅動廠商也都做了更新。可以看一下jar包裡面的META-INF/services目錄,裡面有一個java.sql.Driver的檔案,檔案裡面包含了驅動的全路徑名。

比如mysql-connector裡面的內容:

com.mysql.jdbc.Driver
com.mysql.fabric.jdbc.FabricMySQLDriver

作者:tracy_668
連結:https://www.jianshu.com/p/f6653220a3e7
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

2.2 Dubbo SPI 示例(增強javaSPI)

Dubbo 並未使用 Java SPI,而是重新實現了一套功能更強的 SPI 機制。Dubbo SPI 的相關邏輯被封裝在了 ExtensionLoader 類中,通過 ExtensionLoader,我們可以載入指定的實現類。Dubbo SPI 所需的配置檔案需放置在 META-INF/dubbo 路徑下,配置內容如下。

optimusPrime = org.apache.spi.OptimusPrime
bumblebee = org.apache.spi.Bumblebee

與 Java SPI 實現類配置不同,Dubbo SPI 是通過鍵值對的方式進行配置,這樣我們可以按需載入指定的實現類。另外,在測試 Dubbo SPI 時,需要在 Robot 介面上標註 @SPI 註解。下面來演示 Dubbo SPI 的用法:

public class DubboSPITest {

    @Test
    public void sayHello() throws Exception {
        ExtensionLoader<Robot> extensionLoader = 
            ExtensionLoader.getExtensionLoader(Robot.class);
        Robot optimusPrime = extensionLoader.getExtension("optimusPrime");//可以獲得明確的實現類
        optimusPrime.sayHello();
        Robot bumblebee = extensionLoader.getExtension("bumblebee");
        bumblebee.sayHello();
    }
}