java SPI思想机制

如何解释

简单概括

  • 全称 Service Provider Interface,其实是一种插件思想,是一种面向接口编程的思想,即 先定义好一组接口功能,让其他用户/服务提供商 实现该功能,然后自己直接调用 别人实现的功能

SPI 和 API

  • API,是开发商先写好实现类,对外提供接口,客户再使用(api 是站在开发者的角度说的)
  • SPI,是客户先定义好接口,然后开发商编写该接口的实现类,客户再使用(spi是站在客户的角度说的)

SPI 实现原理(重要-线程上下文类加载器)

  • spi 的实现主要依赖 类加载器 + 线程上下文类加载器,简单来说,其他服务商提供 对应的的实现类.class,客户只需要使用 类加载器加载这些类就可以使用了,但是 现有的 双亲委派模型下 是不支持的。
    • 前提
    • 子加载器所加载的类能够访问父加载器所加载的类。(双亲委派运行机制)
    • 父加载器所加载的类无法访问到子加载器所加载的类。
  • 借助 线程上下文类加载器(Context Classloader) 可以实现 父加载器访问子加载器 加载的类
    • 在双亲委托模型下,类加载是由下至上的,即下层的类加载器会委托上层进行加载。
    • 但是对于SPI来说,有些接口是Java核心库所提供的,而Java核心库是由启动类加载器来加载的,而这些接口的实现却来自于不同的jar包(厂商提供), Java的启动类加载器是不会加载其他来源的jar包,这样传统的双亲委托模型就无法满足SPI的要求。
    • 而通过给当前线程设置上下文类加载器,就可以由设置的上下文类加载器来实现对于接口实现类的加载。

如何使用

  1. ClassPath 下需要一个目录: META/services
  2. 目录里放一个配置文件
    1. 文件名:需要扩展的接口的 全限定接口名
    2. 文件内容:已经实现的类的 全限定类名(包名+基础类名)
  3. 通过 java.util 包里的 ServiceLoad() 方法动态加载 需要的实现类

一个Demo

功能介绍

  • 自己的程序提供 Search 接口,其他服务商实现 多种搜索,包括:FileSearch, DatabaseSearch
  • 在自己的程序里通过 SPI 使用服务商实现的 FileSearch, DatabaseSearch

使用效果(直接在本地模拟服务商提供服务)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

使用效果(通过 jar 的方式引入)

  • 埋坑…

应用分析

  • jdbc, spring, jar,
  • 埋坑…

参考文章

  • https://juejin.cn/post/6998044832199344142
  • https://pdai.tech/md/java/advanced/java-advanced-spi.html
  • https://zhuanlan.zhihu.com/p/28909673
  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值