日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java SPI机制学习之开发实例

發(fā)布時間:2023/11/16 java 52 coder
生活随笔 收集整理的這篇文章主要介紹了 Java SPI机制学习之开发实例 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原創(chuàng)/朱季謙

在該文章正式開始前,先對 Java SPI是什么做一個簡單的介紹。

SPI,是Service Provider Interface的縮寫,即服務(wù)提供者接口,它允許開發(fā)人員定義一組接口,并由供應(yīng)方或者第三方提供具體實現(xiàn)。這種機制能夠讓應(yīng)用程序動態(tài)加載及執(zhí)行各種接口實現(xiàn)。

根據(jù)名字來理解,比較抽象,舉一個例子來說明。

假如,假如Maven項目里有這樣一個interface接口,接口全名“com.zhu.service.UserService”——

package com.zhu.service;

public interface UserService {
    void getName();
}

創(chuàng)建一個“com.zhu.service.impl.AUserServiceImpl”實現(xiàn)類——

public class AUserServiceImpl implements UserService {
    @Override
    public void getName() {
        System.out.println("這是A用戶姓名");
    }
}

接著在resource資源里,創(chuàng)建一個META-INF.services目錄,在該目錄里,創(chuàng)建一個文件名與接口com.zhu.service.UserService一致的文件——

該com.zhu.service.UserService文件里寫下com.zhu.service.impl.UserServiceImpl類名字——

這時候,就可以基于Java SPI動態(tài)加載到接口的實現(xiàn)類并執(zhí)行了,我們寫一個簡單的測試類做驗證——

public class Test {
    public static void main(String[] args) {
        ServiceLoader<UserService> serviceLoader = ServiceLoader.load(UserService.class);
        for (UserService service : serviceLoader) {
            service.getName();
        }
    }
}

執(zhí)行該代碼,ServiceLoader會加載到META-INF.services目錄下的配置文件,找到對應(yīng)接口全名文件,讀取文件里的類名,再通過反射就可以進(jìn)行實現(xiàn)類的實例化。既然能找到實現(xiàn)類的對象,那么不就可以基于父類引用指向子類對象,進(jìn)而調(diào)用到實現(xiàn)類的getName()方法。該方法里執(zhí)行打印語句 System.out.println("打印用戶姓名"),打印結(jié)果如下,說明基于接口UserService,在程序動態(tài)加載并執(zhí)行UserService接口實現(xiàn)。

Java SPI的機制玩法,就如上文這一整個過程的實現(xiàn)。

該機制存在一個缺陷,假如該接口對應(yīng)的文件存在多份實現(xiàn)類,那么,它都會一起執(zhí)行了。

我們增加多一個實現(xiàn)類BUserServiceImpl——

public class BUserServiceImpl implements UserService {
    @Override
    public void getName() {
        System.out.println("這是B用戶姓名");
    }
}

然后,在resource資源里的META-INF.services目錄接口對應(yīng)com.zhu.service.UserService文件里,將BUserServiceImpl實現(xiàn)類的全名增加到文件里——

其他原有的代碼無需改動,直接執(zhí)行Test的main方法,打印結(jié)果如下,可以看到,新增的BUserServiceImpl實現(xiàn)類的getName()也被運行了。

這就說明,Java SPI機制會將文件里配置的所有實現(xiàn)類都動態(tài)加載運行,稍微思考了一下,不難發(fā)現(xiàn),若當(dāng)中某個實現(xiàn)類的getName()出現(xiàn)異常,那么后面還沒有執(zhí)行到的其他實現(xiàn)類就會終止了。

因此,Dubbo框架在設(shè)計SPI機制時,只是參考了Java SPI的實現(xiàn),但沒有照搬,相比Java,Dubbo增強了SPI機制,可以針對請求動態(tài)得選擇需要的接口實現(xiàn)類來運行,更加靈活方便。我在自己的另一邊原創(chuàng)博文中,詳細(xì)介紹過Dubbo SPI的原理,感興趣的小伙伴可以閱讀——《Dubbo2.7的Dubbo SPI實現(xiàn)原理細(xì)節(jié)》

SPI機制的優(yōu)點很明顯,當(dāng)我們需要基于已有接口新增一個實現(xiàn)類功能時,只需要新增一個實現(xiàn)類代碼,無需在原有代碼邏輯上做改動,就可以實現(xiàn)新增類的功能邏輯了。

這種場景比較適合在報表或者處理Excel文檔情況下,需針對一個新報表或者Excel做相應(yīng)定制化處理,只需要基于SPI已有接口新增一個實現(xiàn)類即可。我會在后續(xù)文章中,將過去應(yīng)用到SPI的實踐經(jīng)驗做一下總結(jié)。

總結(jié)

以上是生活随笔為你收集整理的Java SPI机制学习之开发实例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。