Java SPI机制学习之开发实例
原創/朱季謙
在該文章正式開始前,先對 Java SPI是什么做一個簡單的介紹。
SPI,是Service Provider Interface的縮寫,即服務提供者接口,它允許開發人員定義一組接口,并由供應方或者第三方提供具體實現。這種機制能夠讓應用程序動態加載及執行各種接口實現。
根據名字來理解,比較抽象,舉一個例子來說明。
假如,假如Maven項目里有這樣一個interface接口,接口全名“com.zhu.service.UserService”——
package com.zhu.service;
public interface UserService {
void getName();
}
創建一個“com.zhu.service.impl.AUserServiceImpl”實現類——
public class AUserServiceImpl implements UserService {
@Override
public void getName() {
System.out.println("這是A用戶姓名");
}
}
接著在resource資源里,創建一個META-INF.services目錄,在該目錄里,創建一個文件名與接口com.zhu.service.UserService一致的文件——
該com.zhu.service.UserService文件里寫下com.zhu.service.impl.UserServiceImpl類名字——
這時候,就可以基于Java SPI動態加載到接口的實現類并執行了,我們寫一個簡單的測試類做驗證——
public class Test {
public static void main(String[] args) {
ServiceLoader<UserService> serviceLoader = ServiceLoader.load(UserService.class);
for (UserService service : serviceLoader) {
service.getName();
}
}
}
執行該代碼,ServiceLoader會加載到META-INF.services目錄下的配置文件,找到對應接口全名文件,讀取文件里的類名,再通過反射就可以進行實現類的實例化。既然能找到實現類的對象,那么不就可以基于父類引用指向子類對象,進而調用到實現類的getName()方法。該方法里執行打印語句 System.out.println("打印用戶姓名"),打印結果如下,說明基于接口UserService,在程序動態加載并執行UserService接口實現。
Java SPI的機制玩法,就如上文這一整個過程的實現。
該機制存在一個缺陷,假如該接口對應的文件存在多份實現類,那么,它都會一起執行了。
我們增加多一個實現類BUserServiceImpl——
public class BUserServiceImpl implements UserService {
@Override
public void getName() {
System.out.println("這是B用戶姓名");
}
}
然后,在resource資源里的META-INF.services目錄接口對應com.zhu.service.UserService文件里,將BUserServiceImpl實現類的全名增加到文件里——
其他原有的代碼無需改動,直接執行Test的main方法,打印結果如下,可以看到,新增的BUserServiceImpl實現類的getName()也被運行了。
這就說明,Java SPI機制會將文件里配置的所有實現類都動態加載運行,稍微思考了一下,不難發現,若當中某個實現類的getName()出現異常,那么后面還沒有執行到的其他實現類就會終止了。
因此,Dubbo框架在設計SPI機制時,只是參考了Java SPI的實現,但沒有照搬,相比Java,Dubbo增強了SPI機制,可以針對請求動態得選擇需要的接口實現類來運行,更加靈活方便。我在自己的另一邊原創博文中,詳細介紹過Dubbo SPI的原理,感興趣的小伙伴可以閱讀——《Dubbo2.7的Dubbo SPI實現原理細節》
SPI機制的優點很明顯,當我們需要基于已有接口新增一個實現類功能時,只需要新增一個實現類代碼,無需在原有代碼邏輯上做改動,就可以實現新增類的功能邏輯了。
這種場景比較適合在報表或者處理Excel文檔情況下,需針對一個新報表或者Excel做相應定制化處理,只需要基于SPI已有接口新增一個實現類即可。我會在后續文章中,將過去應用到SPI的實踐經驗做一下總結。
總結
以上是生活随笔為你收集整理的Java SPI机制学习之开发实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 11.11
- 下一篇: Java SPI机制总结系列之万字详细图