spi机制是什么意思,Spi机制

  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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: