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();
}
}