最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java SPI與Spring Boot SPI的區(qū)別實(shí)戰(zhàn)指南

 更新時(shí)間:2025年12月11日 11:05:58   作者:不如打代碼KK  
本文詳細(xì)解析了JavaSPI和SpringBootSPI的區(qū)別,并通過(guò)實(shí)戰(zhàn)示例展示了如何在SpringBoot項(xiàng)目中使用SpringBootSPI實(shí)現(xiàn)可擴(kuò)展的支付服務(wù),本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

Java SPI與Spring Boot SPI:區(qū)別解析與實(shí)戰(zhàn)指南

作為一個(gè)摸爬滾打10年的Java老炮,本文將從“理論解析”到“實(shí)戰(zhàn)落地”,全面梳理SPI(服務(wù)提供接口)機(jī)制,重點(diǎn)對(duì)比原生Java SPI和Spring Boot SPI的核心差異,并附上可直接運(yùn)行的Spring Boot SPI實(shí)戰(zhàn)模板,幫你徹底搞懂并用好這個(gè)“解耦神器”。

一、基礎(chǔ)認(rèn)知:SPI到底是什么?

SPI(Service Provider Interface)本質(zhì)是**“接口定義標(biāo)準(zhǔn),第三方實(shí)現(xiàn),運(yùn)行時(shí)動(dòng)態(tài)加載”的設(shè)計(jì)模式——核心目標(biāo)是解耦**:讓“接口規(guī)范制定方”與“接口實(shí)現(xiàn)提供方”徹底分離,避免硬編碼依賴,實(shí)現(xiàn)插件化、可擴(kuò)展的開(kāi)發(fā)模式。

舉個(gè)實(shí)際場(chǎng)景:JDBC規(guī)范由Sun公司定義(接口方),MySQL、Oracle等數(shù)據(jù)庫(kù)廠商提供各自的實(shí)現(xiàn)(實(shí)現(xiàn)方),開(kāi)發(fā)者無(wú)需修改代碼,只需引入對(duì)應(yīng)數(shù)據(jù)庫(kù)的驅(qū)動(dòng)包,就能通過(guò)統(tǒng)一的JDBC接口操作不同數(shù)據(jù)庫(kù)——這就是SPI機(jī)制的典型應(yīng)用。

二、Java SPI:JDK原生的“基礎(chǔ)款”

Java SPI是JDK自帶的標(biāo)準(zhǔn)機(jī)制(從JDK1.6開(kāi)始支持),屬于“原生基礎(chǔ)工具”,優(yōu)點(diǎn)是不依賴任何框架,但缺點(diǎn)也很明顯:功能簡(jiǎn)陋、配置繁瑣、缺乏企業(yè)級(jí)特性。

2.1 Java SPI的核心邏輯

  • 接口方:定義頂層服務(wù)接口(如支付標(biāo)準(zhǔn)IPayService);
  • 實(shí)現(xiàn)方:第三方根據(jù)接口規(guī)范編寫具體實(shí)現(xiàn)類(如AliPayService);
  • 配置文件:在實(shí)現(xiàn)方項(xiàng)目的META-INF/services/目錄下,創(chuàng)建以“接口全限定名”命名的文件,文件內(nèi)容為實(shí)現(xiàn)類的全限定名;
  • 加載方式:調(diào)用方通過(guò)JDK自帶的ServiceLoader類,動(dòng)態(tài)加載所有符合規(guī)范的實(shí)現(xiàn)類。

2.2 Java SPI實(shí)戰(zhàn)示例

步驟1:定義服務(wù)接口(接口方)

// 支付服務(wù)接口(規(guī)范定義)
public interface IPayService {
    // 支付核心方法
    void pay();
}

步驟2:編寫實(shí)現(xiàn)類(實(shí)現(xiàn)方)

// 支付寶支付實(shí)現(xiàn)
public class AliPayService implements IPayService {
    @Override
    public void pay() {
        System.out.println("Java SPI - 支付寶支付成功");
    }
}
// 微信支付實(shí)現(xiàn)
public class WxPayService implements IPayService {
    @Override
    public void pay() {
        System.out.println("Java SPI - 微信支付成功");
    }
}

步驟3:配置SPI文件

resources目錄下創(chuàng)建路徑META-INF/services/,并新建文件com.example.IPayService(接口全限定名),文件內(nèi)容如下:

com.example.AliPayService
com.example.WxPayService

步驟4:加載并使用實(shí)現(xiàn)類

public class SpiTest {
    public static void main(String[] args) {
        // 1. 通過(guò)ServiceLoader加載所有實(shí)現(xiàn)類
        ServiceLoader<IPayService> loader = ServiceLoader.load(IPayService.class);
        // 2. 遍歷調(diào)用實(shí)現(xiàn)類方法
        for (IPayService payService : loader) {
            payService.pay();
        }
    }
}

運(yùn)行結(jié)果

Java SPI - 支付寶支付成功
Java SPI - 微信支付成功

2.3 Java SPI的核心痛點(diǎn)

  • 全量加載,無(wú)法按需篩選ServiceLoader會(huì)加載所有配置的實(shí)現(xiàn)類,不能根據(jù)條件動(dòng)態(tài)選擇;
  • 無(wú)依賴注入能力:加載的實(shí)現(xiàn)類是“裸對(duì)象”,無(wú)法集成Spring的IOC、AOP等特性;
  • 配置路徑嚴(yán)苛:必須嚴(yán)格遵循META-INF/services/接口全限定名的格式,易出錯(cuò);
  • 缺乏生命周期管理:實(shí)現(xiàn)類的創(chuàng)建、銷毀全靠手動(dòng)控制,無(wú)統(tǒng)一管理機(jī)制。

三、Spring Boot SPI:Spring生態(tài)的“增強(qiáng)版”

Spring Boot SPI是基于Spring IOC容器的增強(qiáng)型SPI機(jī)制——它并非對(duì)Java SPI的顛覆,而是在其基礎(chǔ)上融入了Spring的核心特性,讓實(shí)現(xiàn)類成為Spring Bean,支持依賴注入、條件加載、生命周期管理等企業(yè)級(jí)能力,是Spring生態(tài)下的SPI最佳實(shí)踐。

3.1 Spring Boot SPI的核心邏輯

  • 接口方:定義頂層服務(wù)接口(與Java SPI一致);
  • 實(shí)現(xiàn)方:編寫實(shí)現(xiàn)類并添加@Component等Spring注解,標(biāo)記為可被掃描的Bean;
  • 配置文件:通過(guò)META-INF/spring.factories(舊版)或META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(Spring Boot 2.7+推薦)配置實(shí)現(xiàn)類;
  • 加載方式:Spring Boot啟動(dòng)時(shí),自動(dòng)掃描配置文件中的實(shí)現(xiàn)類,將其注冊(cè)到IOC容器,調(diào)用方通過(guò)@Autowired即可注入使用。

3.2 Spring Boot SPI實(shí)戰(zhàn)模板(可直接運(yùn)行)

本模板基于Spring Boot 2.7+版本,實(shí)現(xiàn)可擴(kuò)展的支付服務(wù)SPI,包含“接口定義、多實(shí)現(xiàn)、配置、測(cè)試”全流程。

步驟1:環(huán)境準(zhǔn)備

核心依賴(Maven的pom.xml):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.10</version>
        <relativePath/>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>spring-boot-spi-demo</artifactId>
    <version>1.0.0</version>
    <name>Spring Boot SPI Demo</name>
    <dependencies>
        <!-- Spring Boot 核心依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency><!-- 測(cè)試依賴(可選) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!-- Spring Boot 打包插件 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.7.10</version>
            </plugin>
        </plugins>
    </build>
</project>

步驟2:定義SPI接口(支付服務(wù)標(biāo)準(zhǔn))

路徑:src/main/java/com/example/spi/IPayService.java

package com.example.spi;
/**
 * 支付服務(wù) SPI 接口(定義標(biāo)準(zhǔn))
 */
public interface IPayService {
    /**
     * 支付方法
     * @return 支付結(jié)果
     */
    String pay();
    /**
     * 獲取支付類型(區(qū)分不同實(shí)現(xiàn))
     * @return 支付類型(如alipay、wxpay)
     */
    String getPayType();
}

步驟3:編寫SPI實(shí)現(xiàn)類(多廠商適配)

3.3.1 支付寶實(shí)現(xiàn)類

路徑:src/main/java/com/example/spi/impl/AliPayService.java

package com.example.spi.impl;
import com.example.spi.IPayService;
import org.springframework.stereotype.Component;
/**
 * 支付寶支付實(shí)現(xiàn)(Spring Bean)
 */
@Component
public class AliPayService implements IPayService {
    @Override
    public String pay() {
        return "支付寶支付成功,訂單號(hào):" + System.currentTimeMillis();
    }
    @Override
    public String getPayType() {
        return "alipay";
    }
}
3.3.2 微信支付實(shí)現(xiàn)類

路徑:src/main/java/com/example/spi/impl/WxPayService.java

package com.example.spi.impl;
import com.example.spi.IPayService;
import org.springframework.stereotype.Component;
/**
 * 微信支付實(shí)現(xiàn)(Spring Bean)
 */
@Component
public class WxPayService implements IPayService {
    @Override
    public String pay() {
        return "微信支付成功,訂單號(hào):" + System.currentTimeMillis();
    }
    @Override
    public String getPayType() {
        return "wxpay";
    }
}

步驟4:配置SPI實(shí)現(xiàn)類(Spring Boot 2.7+規(guī)范)

Spring Boot 2.7+ 廢棄了spring.factories,推薦使用AutoConfiguration.imports配置,實(shí)現(xiàn)類會(huì)被自動(dòng)注冊(cè)到Spring容器。

  • 創(chuàng)建配置文件路徑:src/main/resources/META-INF/spring/
  • 新建文件:org.springframework.boot.autoconfigure.AutoConfiguration.imports
  • 寫入實(shí)現(xiàn)類全限定名:

com.example.spi.impl.AliPayService com.example.spi.impl.WxPayService

步驟5:編寫啟動(dòng)類與測(cè)試邏輯

路徑:src/main/java/com/example/SpringBootSpiApplication.java

package com.example;
import com.example.spi.IPayService;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import java.util.List;
/**
 * Spring Boot SPI 啟動(dòng)類
 */
@SpringBootApplication
public class SpringBootSpiApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootSpiApplication.class, args);
    }
    /**
     * 項(xiàng)目啟動(dòng)后自動(dòng)執(zhí)行:測(cè)試SPI加載效果
     * @param payServices 自動(dòng)注入所有IPayService實(shí)現(xiàn)類(Spring特性)
     * @return CommandLineRunner
     */
    @Bean
    public CommandLineRunner testSpi(List<IPayService> payServices) {
        return args -> {
            System.out.println("===== Spring Boot SPI 加載結(jié)果 =====");
            // 遍歷所有支付實(shí)現(xiàn)
            for (IPayService payService : payServices) {
                System.out.println("支付類型:" + payService.getPayType());
                System.out.println("支付結(jié)果:" + payService.pay());
                System.out.println("--------------------------------");
            }
        };
    }
}

步驟6:運(yùn)行測(cè)試與擴(kuò)展

6.1 啟動(dòng)項(xiàng)目,查看結(jié)果

運(yùn)行啟動(dòng)類的main方法,控制臺(tái)輸出如下:

===== Spring Boot SPI 加載結(jié)果 =====
支付類型:alipay
支付結(jié)果:支付寶支付成功,訂單號(hào):1733875000000
--------------------------------
支付類型:wxpay
支付結(jié)果:微信支付成功,訂單號(hào):1733875000001
--------------------------------

6.2 擴(kuò)展新實(shí)現(xiàn)(銀聯(lián)支付)

新增實(shí)現(xiàn)類后,僅需更新配置文件,無(wú)需修改原有代碼(符合開(kāi)閉原則):

新增銀聯(lián)支付實(shí)現(xiàn)類:

package com.example.spi.impl;
import com.example.spi.IPayService;
import org.springframework.stereotype.Component;
@Component
public class UnionPayService implements IPayService {
@Override
public String pay() {
return “銀聯(lián)支付成功,訂單號(hào):” + System.currentTimeMillis();
}
@Override
public String getPayType() {
    return "unionpay";
}

}

  • 更新配置文件AutoConfiguration.imports,新增一行:
  • com.example.spi.impl.UnionPayService
  • 重啟項(xiàng)目,自動(dòng)加載新實(shí)現(xiàn):
  • `===== Spring Boot SPI 加載結(jié)果 =====

支付類型:alipay
支付結(jié)果:支付寶支付成功,訂單號(hào):1733875100000

支付類型:wxpay支付結(jié)果:微信支付成功,訂單號(hào):1733875100001

支付類型:unionpay
支付結(jié)果:銀聯(lián)支付成功,訂單號(hào):1733875100002
--------------------------------`

四、Java SPI vs Spring Boot SPI:核心區(qū)別對(duì)比

通過(guò)前面的理論與實(shí)戰(zhàn),兩者的差異已清晰呈現(xiàn),下面用表格系統(tǒng)總結(jié):

對(duì)比維度Java SPISpring Boot SPI
依賴環(huán)境JDK原生,無(wú)任何框架依賴依賴Spring IOC容器,需Spring Boot環(huán)境
實(shí)現(xiàn)類管理裸對(duì)象,無(wú)生命周期管理Spring Bean,支持完整生命周期(初始化、銷毀)
依賴注入能力無(wú),需手動(dòng)管理依賴支持@Autowired、@Value等Spring注入特性
配置方式固定路徑META-INF/services/接口全限定名靈活,支持spring.factories(舊)、AutoConfiguration.imports(新)
加載特性全量加載,無(wú)法條件篩選支持@ConditionalOnProperty等條件注解,按需加載
集成能力僅加載實(shí)現(xiàn)類,無(wú)擴(kuò)展能力無(wú)縫集成Spring AOP、事務(wù)、監(jiān)控等生態(tài)特性
適用場(chǎng)景基礎(chǔ)組件、跨框架工具(如JDBC驅(qū)動(dòng)、日志框架)Spring Boot項(xiàng)目、微服務(wù)組件、企業(yè)級(jí)插件開(kāi)發(fā)

五、實(shí)戰(zhàn)選型與進(jìn)階技巧

5.1 選型建議

  • 若開(kāi)發(fā)通用基礎(chǔ)組件(如工具類、驅(qū)動(dòng)),需跨框架兼容:選Java SPI;
  • 若在Spring Boot生態(tài)內(nèi)開(kāi)發(fā)(如微服務(wù)、業(yè)務(wù)插件):優(yōu)先選Spring Boot SPI,享受生態(tài)便利;
  • 典型案例參考:MyBatis、Spring Cloud組件均采用Spring Boot SPI實(shí)現(xiàn)擴(kuò)展。

5.2 進(jìn)階技巧:條件加載

通過(guò)Spring條件注解,實(shí)現(xiàn)“配置開(kāi)關(guān)控制實(shí)現(xiàn)類加載”,示例:

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@Component
// 僅當(dāng)配置文件中pay.enable.unionpay=true時(shí),才加載該實(shí)現(xiàn)
@ConditionalOnProperty(name = "pay.enable.unionpay", havingValue = "true")
public class UnionPayService implements IPayService {
    // 實(shí)現(xiàn)代碼...
}

application.yml中配置:

pay:
  enable:
    unionpay: true # 開(kāi)啟銀聯(lián)支付實(shí)現(xiàn)加載

5.3 進(jìn)階技巧:實(shí)現(xiàn)類排序

通過(guò)@Order注解控制實(shí)現(xiàn)類的加載順序:

@Component
@Order(1) // 數(shù)字越小,順序越靠前
public class AliPayService implements IPayService { ... }
@Component
@Order(2)
public class WxPayService implements IPayService { ... }

SPI的核心是“解耦與擴(kuò)展”,Java SPI是基礎(chǔ)實(shí)現(xiàn),保證了通用性;Spring Boot SPI是生態(tài)增強(qiáng),提升了企業(yè)級(jí)開(kāi)發(fā)效率。實(shí)際開(kāi)發(fā)中,需結(jié)合場(chǎng)景選擇合適的方式——而在Spring Boot主導(dǎo)的當(dāng)下,Spring Boot SPI無(wú)疑是更貼合企業(yè)需求的選擇,其靈活的配置、強(qiáng)大的依賴管理和生態(tài)集成能力,能大幅降低插件化開(kāi)發(fā)的成本。

到此這篇關(guān)于Java SPI與Spring Boot SPI的區(qū)別實(shí)戰(zhàn)指南的文章就介紹到這了,更多相關(guān)Java SPI與Spring Boot SPI區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java遞歸實(shí)現(xiàn)菜單樹(shù)的方法詳解

    Java遞歸實(shí)現(xiàn)菜單樹(shù)的方法詳解

    這篇文章主要為大家詳細(xì)介紹了Java遞歸實(shí)現(xiàn)菜單樹(shù)的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • Java基礎(chǔ)之類型封裝器示例

    Java基礎(chǔ)之類型封裝器示例

    這篇文章主要介紹了Java基礎(chǔ)之類型封裝器,結(jié)合實(shí)例形式分析了java類型封裝相關(guān)原理與操作技巧,需要的朋友可以參考下
    2019-08-08
  • RocketMQ源碼解析topic創(chuàng)建機(jī)制詳解

    RocketMQ源碼解析topic創(chuàng)建機(jī)制詳解

    這篇文章主要為大家介紹了RocketMQ源碼解析topic創(chuàng)建機(jī)制詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • 圖文詳解Java中的字節(jié)輸入與輸出流

    圖文詳解Java中的字節(jié)輸入與輸出流

    在Java中所有數(shù)據(jù)都是使用流讀寫的,流是一組有序的數(shù)據(jù)序列,將數(shù)據(jù)從一個(gè)地方帶到另一個(gè)地方,這篇文章主要給大家介紹了關(guān)于Java中字節(jié)輸入與輸出流的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • java 獲取中文拼音首字母及全拼的實(shí)踐

    java 獲取中文拼音首字母及全拼的實(shí)踐

    本文主要介紹了java 獲取中文拼音首字母及全拼的實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • 如何利用泛型封裝通用的service層

    如何利用泛型封裝通用的service層

    這篇文章主要介紹了如何利用泛型封裝通用的service層,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Java 入門圖形用戶界面設(shè)計(jì)之事件處理上

    Java 入門圖形用戶界面設(shè)計(jì)之事件處理上

    圖形界面(簡(jiǎn)稱GUI)是指采用圖形方式顯示的計(jì)算機(jī)操作用戶界面。與早期計(jì)算機(jī)使用的命令行界面相比,圖形界面對(duì)于用戶來(lái)說(shuō)在視覺(jué)上更易于接受,本篇精講Java語(yǔ)言中關(guān)于圖形用戶界面的事件處理
    2022-02-02
  • spring boot2結(jié)合mybatis增刪改查的實(shí)現(xiàn)

    spring boot2結(jié)合mybatis增刪改查的實(shí)現(xiàn)

    這篇文章主要給大家介紹了關(guān)于spring boot2結(jié)合mybatis增刪改查的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用spring boot2具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Java中隨機(jī)數(shù)生成的代碼實(shí)現(xiàn)

    Java中隨機(jī)數(shù)生成的代碼實(shí)現(xiàn)

    在編程中,隨機(jī)數(shù)生成是一個(gè)常見(jiàn)的需求,無(wú)論是模擬數(shù)據(jù)、游戲開(kāi)發(fā)、測(cè)試用例生成,還是簡(jiǎn)單的抽獎(jiǎng)邏輯,都可能需要隨機(jī)數(shù),Java提供了多種生成隨機(jī)數(shù)的方式,本文將通過(guò)兩個(gè)實(shí)際案例,詳細(xì)介紹如何在Java中生成隨機(jī)數(shù),需要的朋友可以參考下
    2025-07-07
  • Maven 常用插件的詳細(xì)整理

    Maven 常用插件的詳細(xì)整理

    這篇文章主要介紹了Maven 常用插件的詳細(xì)整理的相關(guān)資料,這里整理了maven的常用插件需要的朋友可以看下,需要的朋友可以參考下
    2017-08-08

最新評(píng)論

崇左市| 年辖:市辖区| 武山县| 罗平县| 蓬溪县| 凤庆县| 广河县| 老河口市| 大理市| 临汾市| 广河县| 广河县| 彭阳县| 泌阳县| 舒城县| 集贤县| 新津县| 巨鹿县| 新蔡县| 会泽县| 罗田县| 板桥市| 抚宁县| 瑞安市| 正安县| 沐川县| 雷州市| 龙山县| 岗巴县| 罗山县| 平原县| 富锦市| 五原县| 定西市| 略阳县| 阜新| 大厂| 樟树市| 乳山市| 杭锦后旗| 深州市|