惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
Netflix TechBlog - Medium
博客园 - 叶小钗
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
V
V2EX
IT之家
IT之家
J
Java Code Geeks
Hacker News - Newest:
Hacker News - Newest: "LLM"
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
GbyAI
GbyAI
D
Docker
S
Secure Thoughts
Recent Announcements
Recent Announcements
Webroot Blog
Webroot Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
云风的 BLOG
云风的 BLOG
博客园_首页
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Security Archives - TechRepublic
Security Archives - TechRepublic
酷 壳 – CoolShell
酷 壳 – CoolShell
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
N
News | PayPal Newsroom
S
Security @ Cisco Blogs
I
InfoQ
Last Week in AI
Last Week in AI
SecWiki News
SecWiki News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
W
WeLiveSecurity
T
Troy Hunt's Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Attack and Defense Labs
Attack and Defense Labs
美团技术团队
T
The Blog of Author Tim Ferriss
Google DeepMind News
Google DeepMind News
Martin Fowler
Martin Fowler
B
Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Scott Helme
Scott Helme
T
Tor Project blog
Know Your Adversary
Know Your Adversary
有赞技术团队
有赞技术团队
Hugging Face - Blog
Hugging Face - Blog
Recorded Future
Recorded Future
C
Cyber Attacks, Cyber Crime and Cyber Security
AI
AI
G
Google Developers Blog

博客园 - 许仙儿

从大括号圣战到人机掰手腕:AI时代,程序员的“累”换了个赛道 Git 文件忽略备忘录:`assume-unchanged` 完全指南 用go写一个微服务gPRC为主RESTful为辅 三号车间张三喜 为什么湖广不太吃鲤鱼 为什么夏天副高会导致伏旱,而冬天的西伯利亚高原又会带来寒流 普通RESTful和MCP调用对比 2026年放假安排 红楼梦龄官病死前和贾蔷同居的情节 古代的时辰,几更天与现在的时间对应关系是什么? 西游记结局评职称 生成一张图,苹果logo是透明冰块,安卓小机器人撒尿到苹果logo,冲出一个豁口 HL7v3和RIM是什么,和传统HL7,FHIR有什么关系 owl(Web Ontology Language)简介 关系型数据库 vs Elasticsearch 早上看到木蜂在抓取掉落到地上的国槐花,还一边打滚。它是否习性懒惰? 常见古文中流行度和水平最高的前100首,按朝代分类 API Blueprint​​ 是一种基于 ​​Markdown​​ 的轻量级 API 描述语言 八卦的符号,读音,名称,代表的事务分别是什么 Spring Boot 中 JdbcTemplate、MyBatis 和 JPA 共用数据源的可行性 win10下python程序报错OPENSSL_Uplink(00007FFD0AC12FE8,08): no OPENSSL_Applink
Java SPI(Service Provider Interface)示例
许仙儿 · 2025-06-24 · via 博客园 - 许仙儿

Java SPI(Service Provider Interface)是一种服务发现机制,允许第三方为接口提供实现,实现解耦动态扩展。核心流程:

  1. 定义服务接口
  2. 提供接口实现(可多个)
  3. 注册实现(在META-INF/services中配置)
  4. 通过ServiceLoader加载服务

完整示例

1. 定义接口

// 文件路径: src/main/java/com/example/LogService.java
package com.example;

public interface LogService {
    void log(String message);
}

2. 实现接口(两个不同实现)

// 文件路径: src/main/java/com/example/ConsoleLogger.java
package com.example;

public class ConsoleLogger implements LogService {
    @Override
    public void log(String message) {
        System.out.println("[Console] " + message);
    }
}
// 文件路径: src/main/java/com/example/FileLogger.java
package com.example;

public class FileLogger implements LogService {
    @Override
    public void log(String message) {
        System.out.println("[File] Log saved: " + message); // 模拟写入文件
    }
}

3. 注册服务实现

在资源目录创建文件:
src/main/resources/META-INF/services/com.example.LogService
内容为实现类的全限定名

com.example.ConsoleLogger
com.example.FileLogger

4. 使用服务

// 文件路径: src/main/java/com/example/MainApp.java
package com.example;

import java.util.ServiceLoader;

public class MainApp {
    public static void main(String[] args) {
        // 加载所有LogService实现
        ServiceLoader<LogService> loggers = ServiceLoader.load(LogService.class);
        
        // 遍历并调用服务
        for (LogService logger : loggers) {
            logger.log("Hello SPI!");
        }
    }
}

运行结果

[Console] Hello SPI!
[File] Log saved: Hello SPI!

关键点说明

  1. 服务注册文件位置
    META-INF/services/接口全限定名(无文件后缀)
  2. 文件内容格式
    每行一个实现类的全限定名(如多实现需换行)
  3. 加载原理
    ServiceLoader通过线程上下文类加载器查找所有META-INF/services下的注册信息
  4. 应用场景
    • JDBC驱动加载(DriverManager
    • SLF4J日志门面
    • Spring Boot自动配置

对比普通接口调用

方式 SPI机制 普通接口调用
耦合度 实现类可独立扩展,完全解耦 需显式依赖具体实现
新增实现 添加JAR包即生效 需修改调用方代码
依赖关系 调用方只依赖接口 调用方依赖接口+具体实现

提示:在Spring Boot中,spring.factories机制是SPI的增强版,原理类似但支持更复杂的自动配置场景。