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

JAVA SPI機制詳解使用方法

 更新時間:2022年07月05日 10:28:08   作者:cloneme01  
Java定義了一套JDBC的接口,但并未提供具體實現(xiàn)類,而是在不同云廠商提供的數(shù)據(jù)庫實現(xiàn)包。這篇文章給大家介紹Java的SPI機制,感興趣的朋友一起看看吧

寫在前面

Java SPI提供了一種為某個接口尋找服務(wù)實現(xiàn)的機制。有點類似IOC的思想,就是將裝配的控制權(quán)移到程序之外,在模塊化設(shè)計中這個機制尤其重要,SPI的核心思想就是解耦。

SPI的調(diào)用流程

什么是SPI

SPI全稱Service Provider Interface,是Java提供的一套用來被第三方實現(xiàn)或者擴展的API,它可以用來啟用框架擴展和替換組件。Java SPI 實際上是“基于接口的編程+策略模式+配置文件”組合實現(xiàn)的動態(tài)加載機制。在面向?qū)ο蟮木幊膛c設(shè)計中,一般推薦模塊之間要基于接口編程,模塊之間不對實現(xiàn)類進行硬編碼,一旦代碼里涉及了具體的實現(xiàn)類,就違反了可拔插的原則,如果需要替換另外一種實現(xiàn),就需要修改代碼。

使用場景

使用Java SPI機制的優(yōu)勢是實現(xiàn)解耦,使得第三方服務(wù)模塊的裝配控制的邏輯與調(diào)用者的業(yè)務(wù)代碼分離,而不是耦合在一起,應(yīng)用程序可以根據(jù)實際業(yè)務(wù)情況啟用框架擴展或替換框架組件,常見的場景如下:
(1). JDBC加載不同類型的驅(qū)動
(2). SLF4J對Log4j/Logback的支持

實現(xiàn)約定

(1). 服務(wù)提供者提供接口的具體實現(xiàn),在JAVA包的META-INF/services目錄下創(chuàng)建一個以“接口全限定名”為命名的文件,內(nèi)容為實現(xiàn)類的全限定名;
(2). 接口具體實現(xiàn)類所在的JAR包需要放在主程序的CLASSPATH中;
(3). 主程序通過java.util.ServiceLoder動態(tài)加載具體的實現(xiàn)模塊,它通過掃描META-INF/services目錄下的配置文件,找到具體實現(xiàn)類并把它加載到JVM中;
(4). SPI的實現(xiàn)類必須攜帶一個不帶參數(shù)的構(gòu)造函數(shù)。

四種角色

(1). 提供某種功能的接口(SLF4J 提供了一組接口類)
(2). 提供某種功能接口的具體實現(xiàn)(每個具體的實現(xiàn)需要包含:META-INF/services目錄下創(chuàng)建一個以“接口全限定名”為命名的文件,內(nèi)容為實現(xiàn)類的全限定名。Log4j/Logback提供了具體的實現(xiàn))
(3). 提供發(fā)現(xiàn)和加載CLASSPATH中所有的接口具體實現(xiàn)的對象
(4). 客戶端(接口的使用者)

關(guān)于JAVA SPI詳細的介紹請看:JAVA - SPI機制使用詳解(一)

基于JAVA原生特性實現(xiàn)的JAVA SPI機制的DEMO

1. 主要角色

主要角色有:接口、多個實現(xiàn)類以及測試客戶端,在每個實現(xiàn)類中需要創(chuàng)建信息文件:resources/META-INF/services/接口全限定名一致的文件。接口、多個實現(xiàn)類以及客戶端分別在不同的MODULE中。

2. 示例代碼

①. 接口:

package com.hadoopx.javax.spi;
public interface Coder {
    public String write();
}

②. 第一個實現(xiàn)類:

package com.hadoopx.javax.spi;
public class Javaer implements Coder {
    public String write() {
        return "I'M JAVA CODER, USE JAVA TO WRITE EVERYTHING.";
    }
}
創(chuàng)建信息說明文件:resources/META-INF/services/com.hadoopx.javax.spi.Coder,
里面的內(nèi)容為:com.hadoopx.javax.spi.Javaer

③. 第二個實現(xiàn)類:

package com.hadoopx.javax.spi;
public class Rubyer implements Coder {
    public String write() {
        return "I'M RUBY CODER, USE RUBY TO WRITE EVERYTHING.";
    }
}
創(chuàng)建信息說明文件:resources/META-INF/services/com.hadoopx.javax.spi.Coder,
里面的內(nèi)容為:com.hadoopx.javax.spi.Rubyer

④. 客戶端:

添加依賴:
<dependencies>
    <dependency>
        <groupId>com.hadoopx</groupId>
        <artifactId>javax-spi001-javaer</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>com.hadoopx</groupId>
        <artifactId>javax-spi001-rubyer</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>
客戶端代碼:
package com.hadoopx.javax.spi;
public class MyTest {
    public static void main(String[] args) {
        ServiceLoader<Coder> s = ServiceLoader.load(Coder.class);
        Iterator<Coder> iterator = s.iterator();
        while (iterator.hasNext()) {
            Coder lang =  iterator.next();
            String content = lang.write();
            System.out.println(content);
        }
    }
}

輸出結(jié)果為:

I'M JAVA CODER, USE JAVA TO WRITE EVERYTHING.
I'M RUBY CODER, USE RUBY TO WRITE EVERYTHING.

3. 說明

在實際的使用過程中,需要指定不同的類型來創(chuàng)建不同的實現(xiàn)類實例。

基于SPRING BOOT實現(xiàn)的JAVA SPI機制的DEMO

注意: 在每個實現(xiàn)類中不需要創(chuàng)建信息文件。

①. 接口:

package com.hadoopx.javax.spi;
public interface Coder {
    public String write();
}

②. 第一個實現(xiàn)類:

package com.hadoopx.javax.spi;
@Service
@Primary
public class Javaer implements Coder {
    public String write() {
        return "I'M JAVA CODER, USE JAVA TO WRITE EVERYTHING.";
    }
}

③. 第二個實現(xiàn)類:

package com.hadoopx.javax.spi;
@Service
public class Rubyer implements Coder {
    public String write() {
        return "I'M RUBY CODER, USE RUBY TO WRITE EVERYTHING.";
    }
}

④. 客戶端一:

添加依賴:
<dependencies>
    <dependency>
        <groupId>com.hadoopx</groupId>
        <artifactId>javax-spi002-javaer</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>com.hadoopx</groupId>
        <artifactId>javax-spi002-rubyer</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>
客戶端代碼:
@RestController
@RequestMapping("/t")
@Api(value = "測試服務(wù)", description = "該服務(wù)僅僅用于完成驗證、學(xué)習(xí)和測試")
public class TestController {
	// 切換不同的服務(wù)
    @Autowired
    @Qualifier("javaer")
    private Coder coder;
    @ApiOperation(value = "測試", notes = "基于SPRING BOOT實現(xiàn)的JAVA SPI機制的DEMO")
    @GetMapping("/spi")
    public String test() {
        System.out.println(coder.write());
        return "ok";
    }
}

輸出結(jié)果為:

I'M JAVA CODER, USE JAVA TO WRITE EVERYTHING.

⑤. 客戶端二:

有時會根據(jù)不同的情況,調(diào)用不同服務(wù)的方法,所以在客戶端中需要多增加下面這個文件:

@Service
public class CoderContext {
	// 通過 @Autowired 把Coder所有的實現(xiàn)類注入到map(coders)中.
	// Spring會查找應(yīng)用的上下文里類型為Coder的Bean, 并把查找到的Bean注入到Map<String, Coder> 或者 List<Coder>中
    @Autowired
    Map<String, Coder> coders;
    public Coder getCoder(String key){
        return coders.get(key);
    }
}
客戶端代碼:
@RestController
@RequestMapping("/t")
@Api(value = "測試服務(wù)", description = "該服務(wù)僅僅用于完成驗證、學(xué)習(xí)和測試")
public class TestController {
    @Autowired
    private CoderContext coderContext;
    @ApiOperation(value = "測試", notes = "基于SPRING BOOT實現(xiàn)的JAVA SPI機制的DEMO")
    @GetMapping("/spi")
    public String test(String type) {
        System.out.println(coderContext.getCoder(type).write());
        return "ok";
    }
}

到此這篇關(guān)于JAVA SPI機制詳解使用方法的文章就介紹到這了,更多相關(guān)JAVA SPI機制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決spring-boot2.0.6中webflux無法獲得請求IP的問題

    解決spring-boot2.0.6中webflux無法獲得請求IP的問題

    這幾天在用 spring-boot 2 的 webflux 重構(gòu)一個工程,寫到了一個需要獲得客戶端請求 IP 的地方,在寫的過程中遇到很多問題,下面小編通過一段代碼給大家介紹解決spring-boot2.0.6中webflux無法獲得請求IP的問題,感興趣的朋友跟隨小編一起看看吧
    2018-10-10
  • Spring?Data?JPA?實體類中常用注解說明

    Spring?Data?JPA?實體類中常用注解說明

    這篇文章主要介紹了Spring?Data?JPA?實體類中常用注解說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 全面了解java中的異常處理

    全面了解java中的異常處理

    java中的異常處理是java語言中的一大重要特性,它分離了接收和處理錯誤代碼。這篇文章非常詳細的講解了java中的這一特性,感興趣的小伙伴一起來學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • java正則匹配HTML中a標(biāo)簽里的中文字符示例

    java正則匹配HTML中a標(biāo)簽里的中文字符示例

    這篇文章主要介紹了java正則匹配HTML中a標(biāo)簽里的中文字符,涉及java中文正則及HTML元素操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2017-01-01
  • SpringBoot入門實現(xiàn)第一個SpringBoot項目

    SpringBoot入門實現(xiàn)第一個SpringBoot項目

    今天我們一起來完成一個簡單的SpringBoot(Hello World)。就把他作為你的第一個SpringBoot項目。具有一定的參考價值,感興趣的可以了解一下
    2021-09-09
  • Object類toString()和equals()方法使用解析

    Object類toString()和equals()方法使用解析

    這篇文章主要介紹了Object類toString()和equals()方法使用解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • SpringCloud Alibaba Seata (收藏版)

    SpringCloud Alibaba Seata (收藏版)

    Seata是一款開源的分布式事務(wù)解決方案,致力于在微服務(wù)架構(gòu)在提供高性能和簡單一樣的分布式事務(wù)服務(wù)。這篇文章主要介紹了SpringCloud Alibaba Seata 的相關(guān)知識,需要的朋友可以參考下
    2020-10-10
  • 一篇文章帶你從java字節(jié)碼層理解i++和++i

    一篇文章帶你從java字節(jié)碼層理解i++和++i

    這篇文章帶你從java字節(jié)碼層理解i++和++i,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-09-09
  • Java之MyBatis的Dao方式以及Dao動態(tài)代理詳解

    Java之MyBatis的Dao方式以及Dao動態(tài)代理詳解

    這篇文章主要介紹了Java之MyBatis的Dao方式以及Dao動態(tài)代理詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • java實現(xiàn)從網(wǎng)上下載圖片到本地的方法

    java實現(xiàn)從網(wǎng)上下載圖片到本地的方法

    這篇文章主要介紹了java實現(xiàn)從網(wǎng)上下載圖片到本地的方法,涉及java針對文件操作的相關(guān)技巧,非常簡單實用,需要的朋友可以參考下
    2015-07-07

最新評論