欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java利用SPI實現(xiàn)解耦的示例詳解

 更新時間:2023年04月07日 11:20:30   作者:少年的我  
SPI的全稱是服務(wù)提供接口,可以用其來啟動框架的擴展和替換組件。本文將利用SPI實現(xiàn)解耦,文中的示例代碼講解詳細,具有一定的借鑒價值,需要的可以參考一下

概述

SPI的全稱是服務(wù)提供接口,可以用其來啟動框架的擴展和替換組件。

其本質(zhì)是利用 接口實現(xiàn)+策略模式+配置文件來實現(xiàn)對實現(xiàn)類的動態(tài)加載。

在具體的使用中,存在一些約定:

(1)規(guī)定在 classPath 的 META-INF/services/ 下,創(chuàng)建該接口的全名稱文件

(2)在該文件中,寫入該接口實現(xiàn)類全稱(路徑+文件名),多個實現(xiàn)類的話,分行寫。

(3)用的2時候,使用 java.util.ServiceLoader 的 load(Interface.class),獲取到實現(xiàn)類,就可以使用了。

值得注意的是,接口實現(xiàn)類必須有一個不帶參數(shù)的構(gòu)造方法。

實現(xiàn)案例

在本應(yīng)用中,存在兩個模塊,分別為A模塊和B模塊,這兩個模塊中,A模塊是主模塊,B是從模塊,B模塊是依賴A模塊的。但是在目前有一個類,該類中實現(xiàn)在B模塊中,A模塊需要調(diào)用這個類的函數(shù),而模塊不能再依賴B模塊,此時需要進行解耦。在本實現(xiàn)中,利用SPI的方式進行解耦實現(xiàn)。具體實現(xiàn)方案為:

(1)在A模塊新建一個接口:MyLogAppender,具體實現(xiàn)為:

/**
 * @author Huang gen(kenfeng)
 * @description 自定義的appender接口
 * @Since 2021/02/21
 **/

public interface MyLogAppender {

    /**
     * 獲取實現(xiàn)的appender
     * @return  返回新建的appender對象
     * */
    Appender getAppender();
}

這個接口很簡單,只是返回一個appender的對象。對于對象的實際操作,在接口的實現(xiàn)中進行操作。

(2)在B模塊添加對這個接口的實現(xiàn),具體的操作為:

/**
 * @author Huang gen(kenfeng)
 * @description 自定義的appender
 * @Since 2021/02/21
 **/
@Component
public class MeshLogAppender extends UnsynchronizedAppenderBase<ILoggingEvent> implements MyLogAppender,ApplicationContextAware {

    private ApplicationContext applicationContext;

    public MeshLogAppender(){ }

    @Override
    public Appender getAppender() {
        MeshLogAppender meshLogAppender = new MeshLogAppender();
        return meshLogAppender;
    }

    @Override
    protected void append(ILoggingEvent iLoggingEvent) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String std = simpleDateFormat.format(new Date(Long.parseLong(String.valueOf(iLoggingEvent.getTimeStamp()))));
        String log = std + "\t" + iLoggingEvent.getLevel() +"\t"+"--- ["+ iLoggingEvent.getThreadName()+"]\t"+iLoggingEvent.getCallerData()[0]+":\t "+iLoggingEvent.getMessage();
        FlowMessage input = new FlowMessage();
        MeshFlowService meshFlowService = SandboxSystemServiceFactory.getService(MeshFlowService.class);
        Map<String, Object> body = new HashMap<>(2);
        body.put("log",log);
        input.setTenantCode(DefaultTenant.get());
        input.setAppCode("epoch");
        input.setFlowCode("log_broadcast");
        input.setBody(body);
        FlowMessage output = meshFlowService.process(input);
        if(!StringUtils.isEmpty(output.getErrorMessage())){
            throw new RuntimeException("發(fā)布日志時,廣播失敗");
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

在該接口的申明和接口的實現(xiàn)中,存在一些小的技巧的實現(xiàn)。在接口中,只聲明一個類的獲取,并沒有實現(xiàn)具體的方法。在實現(xiàn)類中,對這個類進行實例化,new一個新的類并返回,此時用戶根據(jù)這個get方法就可以拿到這個實現(xiàn)類,然后進行實現(xiàn)類的一些操作。這樣寫可以帶來兩個好處: i. 代碼更簡潔,接口的代碼簡單易懂 ii. 可以在實現(xiàn)類的構(gòu)造方法中注入一些參數(shù),當用戶使用時,直接在get方法里面注入即可。

(3) 在實現(xiàn)類所在文件夾下,也就是sandbox-app-epoch-starter中添加一個配置文件,其配置文件的路徑默認為: resources/META-INF/services/,在這個文件夾下新建一個問題,文件名為接口的路徑,內(nèi)容是實現(xiàn)類的路徑。由此可以實現(xiàn)接口-->實現(xiàn)類的映射。

如上圖中,文件名為:com.alibaba.halo.sandbox.app.util.MyLogAppender

其文件中的內(nèi)容為:com.alibaba.lattice2.epoch.util.MeshLogAppender

其原理是,當用戶使用接口時,會掃描項目下的所有文件,查找文件名為com.alibaba.halo.sandbox.app.util.MyLogAppender,然后根據(jù)其內(nèi)容來查找到相關(guān)的實現(xiàn)類

(4)在A,可以直接使用接口來進行調(diào)用,具體實現(xiàn)如下:

				ServiceLoader<MyLogAppender> myLoaderInterfaceServiceLoader = ServiceLoader.load(MyLogAppender.class);
        Iterator<MyLogAppender> myLoaderInterfaceIterator = myLoaderInterfaceServiceLoader.iterator();
        while (myLoaderInterfaceIterator.hasNext()){
            MyLogAppender myLoaderInterface = myLoaderInterfaceIterator.next();

            Appender newAppender = myLoaderInterface.getAppender();
            newAppender.setName("application");
            newAppender.setContext(loggerContext);
            newAppender.start();
            rootLogger.addAppender(newAppender);
        }

從上面可以看到,其可以直接調(diào)用MyLogAppender接口,利用這個接口獲取的Appender,之后直接賦值即可。

優(yōu)勢和不足

優(yōu)點:可以實現(xiàn)代碼的解耦

缺點:存在多個實現(xiàn)類的話,無法根據(jù)某個參數(shù)或者標志位獲取實例,只能通過遍歷獲取,沒有實現(xiàn)所謂的懶加載

到此這篇關(guān)于Java利用SPI實現(xiàn)解耦的示例詳解的文章就介紹到這了,更多相關(guān)Java SPI解耦內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot用多線程批量導(dǎo)入數(shù)據(jù)庫實現(xiàn)方法

    SpringBoot用多線程批量導(dǎo)入數(shù)據(jù)庫實現(xiàn)方法

    這篇文章主要介紹了SpringBoot用多線程批量導(dǎo)入數(shù)據(jù)庫實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-02-02
  • Java多線程 線程狀態(tài)原理詳解

    Java多線程 線程狀態(tài)原理詳解

    這篇文章主要介紹了Java多線程 線程狀態(tài)原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • SpringCloud修改Feign日志記錄級別過程淺析

    SpringCloud修改Feign日志記錄級別過程淺析

    OpenFeign源于Netflix的Feign,是http通信的客戶端。屏蔽了網(wǎng)絡(luò)通信的細節(jié),直接面向接口的方式開發(fā),讓開發(fā)者感知不到網(wǎng)絡(luò)通信細節(jié)。所有遠程調(diào)用,都像調(diào)用本地方法一樣完成
    2023-02-02
  • Java并發(fā)編程Lock?Condition和ReentrantLock基本原理

    Java并發(fā)編程Lock?Condition和ReentrantLock基本原理

    這篇文章主要介紹了Java并發(fā)編程Lock?Condition和ReentrantLock基本原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • Java處理時間格式CST和GMT轉(zhuǎn)換方法示例

    Java處理時間格式CST和GMT轉(zhuǎn)換方法示例

    這篇文章主要給大家介紹了關(guān)于Java處理時間格式CST和GMT轉(zhuǎn)換方法的相關(guān)資料,相信很多小伙伴在時間格式轉(zhuǎn)換的時候非常頭疼,文中通過代碼示例介紹的非常詳細,需要的朋友可以參考下
    2023-09-09
  • 基于HttpClient上傳文件中文名亂碼的解決

    基于HttpClient上傳文件中文名亂碼的解決

    這篇文章主要介紹了HttpClient上傳文件中文名亂碼的解決方案,具有很好的參考價值,希望對大家有所幫助。
    2021-07-07
  • 解決ThingsBoard編譯報錯問題:Failure?to?find?org.gradle:gradle-tooling-api:jar:6.3

    解決ThingsBoard編譯報錯問題:Failure?to?find?org.gradle:gradle-too

    這篇文章主要介紹了ThingsBoard編譯報錯:Failure?to?find?org.gradle:gradle-tooling-api:jar:6.3,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • Java中Random簡介_動力節(jié)點Java學(xué)院整理

    Java中Random簡介_動力節(jié)點Java學(xué)院整理

    本文詳細給大家介紹了Java中Random簡介相關(guān)知識,非常不錯,具有參考借鑒價值,需要的朋友參考下吧
    2017-06-06
  • mybatis-plus分頁查詢?nèi)N方法小結(jié)

    mybatis-plus分頁查詢?nèi)N方法小結(jié)

    本文主要介紹了mybatis-plus分頁查詢?nèi)N方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • Java方法重載Overload原理及使用解析

    Java方法重載Overload原理及使用解析

    這篇文章主要介紹了Java方法重載Overload原理及使用解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11

最新評論