spi机制是什么意思,Spi机制
1.SPI机制是什么?Spi(服务提供者接口)是内置于JDK中的服务提供发现机制。SPI是一种动态替换发现机制,也是一种优秀的解耦思想。
spi的工作原理是,在类路径路径下的META-INF/services文件夹中,用接口的全限定名来命名文件名,接口的实现写在文件中。然后加载资源,读取文件的内容(接口实现的完全限定名),然后加载类。
Spi可以灵活地将接口和实现分开,这样api提供者只需提供接口,第三方就可以实现。
优势:
使用Java SPI机制的好处是实现解耦,使第三方服务模块的组装控制逻辑与调用方的业务代码分离,而不是耦合在一起。应用程序可以根据实际业务情况启用框架扩展或替换框架组件。
缺点:
虽然可以把ServiceLoader看作是延迟加载,但是只能通过遍历获得,即接口的所有实现类都加载实例化一次。如果不想用一些实现类,也是加载实例化,造成浪费。获取实现类的方式不够灵活,只能通过迭代器获取,无法根据某个参数获取对应的实现类。
多个并发线程使用ServiceLoader类的多个实例是不安全的。
第二,如何使用SPI。现在有这样一个场景:当我的项目中有任何支付模块的时候,我就用什么样的支付模块。比如有支付宝支付模块,我会选择支付宝;如果有微信支付模块,我会选择微信支付;如果同时有多个,我会默认选择第一个。这时候我们就可以用SPI了。先看看怎么用吧。
1.创建META-INF/services文件夹,然后用Pay接口的完全限定名创建一个文件。
2.在文件中写下你要实现哪个Pay的实现类(支付宝,微信支付,银行卡支付)。请注意,它也应该是一个完全限定的名称。如果是支付宝支付的模块,上面文件的内容:com。陶龙. dubbo.spi.strategy .支付宝
3.获得报酬并打电话
Get和调用逻辑,我会修改上面策略模式中Context的invokerStrategy方法,假设默认使用第一个。
public void invokeStrategy(){
service loader Pay payservice loader=service loader . load(Pay . class);
迭代器Pay iterator=payserviceloader . iterator();
if (iterator.hasNext()){
iterator.next()。pay();
}
}三。SPI的优秀实现案例我们来看一个使用上面SPI的真实例子——数据库驱动。
我们知道当我们的项目使用引用mysql的驱动pom依赖时,我们的项目会自动选择使用mysql驱动,我们甚至不需要手动加载。我们来看看它的具体实现。
1.先看java.sql.Driver的类,相当于定义了一个规范。
2.其次,看看mysql驱动包的META-INF/services文件夹下有没有指定的文件。
很熟悉,名字叫java.sql.Driver
3.打开文件并检查其内容。
这里,我们可以看到我们的mysql的驱动程序。基本上,这里确认了这也是使用SPI实现的。顺便说一下,现在,我们为什么不需要使用Class.forName()来加载驱动程序呢?这是因为DriverManager使用SPI的机制已经帮我们加载了。我们来看看DriverManager的类。
文件名和文件内容都是完全限定名,所以通过反射很容易创建相应的类。
事实上,我们知道现有框架中的SPI机制是因为我们最近在阅读SpringBoot代码时发现了它。我们知道SprngBoot中的许多配置和实现都有默认实现。我们只需要修改一些配置,比如数据库配置,在配置文件中写入相应的url、用户名和密码就可以使用了。事实上,他在这里通过SPI实现了这一点。
然而,Spring只使用了与JDK相同的原理。
JDK用的工具类是ServiceLoaderSpring,JDK用的类是SpringFactoriesLoader,在org . spring framework . core . io . support包里。
差异:
不同路径的文件放在meta-INF/spring.factors中。
版权归作者所有:原创作品来自博主、程序员,转载授权请联系作者,否则将追究法律责任。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。