脚本宝典收集整理的这篇文章主要介绍了一文搞懂Java的SPI机制,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
SPI,Service Provider Interface,一种服务发现机制。
有了SPI,即可实现服务接口与服务实现的解耦:Dubbo SPI 实现方式对以上两点进行了业务优化。
LazyIterator#hasNextService 读取 META-INF/services 下的配置文件,获得所有能被实例化的类的名称,并完成 SPI 配置文件的解析
LazyIterator#nextService 负责实例化 hasNextService() 读到的实现类,并将实例化后的对象存放到 providers 集合中缓存
如某接口有3个实现类,那系统运行时,该接口到底选择哪个实现类呢? 这时就需要SPI,根据指定或默认配置,找到对应实现类,加载进来,然后使用该实现类实例。
如下系统运行时,加载配置,用实现A2实例化一个对象来提供服务:
再如,你要通过jar包给某个接口提供实现,就在自己jar包的META-INF/services/
目录下放一个接口同名文件,指定接口的实现是自己这个jar包里的某类即可: 别人用这个接口,然后用你的jar包,就会在运行时通过你的jar包指定文件找到这个接口该用哪个实现类。这是JDK内置提供的功能。
我就不定义在 META-INF/services 下面行不行?就想定义在别的地方可以吗?
No!JDK 已经规定好配置路径,你若随便定义,类加载器可就不知道去哪里加载了
假设你有个工程P,有个接口A,A在P无实现类,系统运行时怎么给A选实现类呢? 可以自己搞个jar包,META-INF/services/
,放上一个文件,文件名即接口名,接口A的实现类=com.javaedge.service.实现类A2
。 让P来依赖你的jar包,等系统运行时,P跑起来了,对于接口A,就会扫描依赖的jar包,看看有没有META-INF/services
文件夹:
比如你开发了一个开源框架,若你想让别人自己写个插件,安排到你的开源框架里中,扩展功能时。
如JDBC。Java定义了一套JDBC的接口,但并未提供具体实现类,而是在不同云厂商提供的数据库实现包。
但项目运行时,要使用JDBC接口的哪些实现类呢?
一般要根据自己使用的数据库驱动jar包,比如我们最常用的MySQL,其mysql-jdbc-connector.jar
里面就有:
如sharding-jdbc 数据加密模块,本身支持 AES 和 MD5 两种加密方式。但若客户端不想用内置的两种加密,偏偏想用 RSA 算法呢?难道每加一种算法,sharding-jdbc 就要发个版本?
sharding-jdbc 可不会这么蠢,首先提供出 EncryptAlgorithm 加密算法接口,并引入 SPI 机制,做到服务接口与服务实现分离的效果。 客户端想要使用自定义加密算法,只需在客户端项目 META-INF/services
的路径下定义接口的全限定名称文件,并在文件内写上加密实现类的全限定名
以上是脚本宝典为你收集整理的一文搞懂Java的SPI机制全部内容,希望文章能够帮你解决一文搞懂Java的SPI机制所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。