在java中使用SPI创建可扩展的应用程序
文章目錄
- 簡介
 - SPI簡介
 - SPI的普通java實現
 - SPI在JPMS模塊化系統下的實現
 - 總結
 
簡介
什么是可擴展的應用程序呢?可擴展的意思是不需要修改原始代碼,就可以擴展應用程序的功能。我們將應用程序做成插件或者模塊。
這樣可以在不修改原應用的基礎上,對系統功能進行升級或者定制化。
本文將會向大家介紹如何通過java中的SPI機制實現這種可擴展的應用程序。
SPI簡介
SPI的全稱是Java Service Provider Interface。是java提供的一種服務發現的機制。
通過遵循相應的規則編寫應用程序之后,就可以使用ServiceLoader來加載相應的服務了。
SPI的實現主要分為4個部分:
SPI的普通java實現
講完SPI的定義,大家可能還是不清楚SPI到底是做什么的,又該怎么使用它。
不用急,我們下面通過一個例子來說明。
首先創建一個module:SPI-service,里面主要定義了一個ModuleService接口:
public interface ModuleService { }然后再分別創建兩個module,作為ModuleService的實現:
public class ModuleServiceA implements ModuleService {public ModuleService getModuleService(){return new ModuleServiceA();} } public class ModuleServiceB implements ModuleService {public ModuleService getModuleService(){return new ModuleServiceB();} }接著分別在兩個module中創建META-INF/services文件夾,并且在里面創建兩個以 Service Provider Interface限定名為名字的文件,這里文件名是:com.flydean.base.service.ModuleService,文件里面存放的是SPI的具體實現類:
com.flydean.base.servicea.ModuleServiceA com.flydean.base.serviceb.ModuleServiceB最后,我們需要創建一個使用SPI的類:
public class ModuleController {public static void main(String[] args) {List<ModuleService> moduleServices = ServiceLoader.load(ModuleService.class).stream().map(ServiceLoader.Provider::get).collect(toList());log.info("{}", moduleServices);} }為了更好的展示擴展應用的實際使用,我們分別創建4個模塊。在實際應用中,只需要將這些jar包加入應用程序的classpath即可。
運行看下輸出結果:
[com.flydean.base.servicea.ModuleServiceA@16f65612, com.flydean.base.serviceb.ModuleServiceB@311d617d]從結果看到,我們獲得了兩個ModuleService。證明系統擴展成功。
SPI在JPMS模塊化系統下的實現
上面我們講的是基本的操作,考慮一下,如果是在JDK9之后,引入了JPMS模塊化系統之后,應該怎么使用SPI呢?
代碼肯定是一樣,我們需要修改的是SPI配置文件。
如果在JPMS中,我們就不需要使用META-INF/services了,我們只需要創建相應的module-info.java文件即可。
先看下SPI模塊的module-info.java文件:
module com.flydean.service {exports com.flydean.service; }這個模塊我們對外暴露了service package,供其他模塊調用。
接下來是SPI的實現模塊:
module com.flydean.servicea {requires com.flydean.service;provides com.flydean.service.ModuleService with com.flydean.servicea.ModuleServiceA;exports com.flydean.servicea; }這里我們使用了provides命令,定義了兩個類的關聯關系。
最后是調用的模塊:
module com.flydean.controller {uses com.flydean.service.ModuleService;requires com.flydean.service;requires lombok;requires slf4j.api; }這里我們使用uses關鍵詞來引用ModuleService。
總結
本文介紹了SPI在模塊化和非模塊化系統中的應用。
本文中的例子:learn-java-base-9-to-20
本文已收錄于 http://www.flydean.com/java-spi-for-extensible-app/
最通俗的解讀,最深刻的干貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!
歡迎關注我的公眾號:「程序那些事」,懂技術,更懂你!
總結
以上是生活随笔為你收集整理的在java中使用SPI创建可扩展的应用程序的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: troubleshoot之:GC调优到底
 - 下一篇: 看动画学算法之:平衡二叉搜索树AVL T