dubbo SPI是不是在炫技?

简介

SPI全称Service Provider Interface,顾名思义,就是接口提供服务。

一般做框架才会用到SPI,就是做抽象层、做标准流程,但是具体服务层要可定制,依赖与具体的业务,就可以使用SPI。

例如,数据驱动,JDK中的java.sql包中基本都是抽象层的东西,不和具体的数据库相关,它怎么实现,就是使用SPI。

当然,要做SPI的实现,也需要对SPI有所了解才行。

简单总结一下:

我定义抽象接口,并面向接口编程提供相应的工具类,提供服务的人来具体实现,其他人使用我的接口,我再使用具体的实现

SPI的优势

  1. 统一标准,可以使用共同的抽象层,否则每一种数据库的每一种驱动都有自己的标准和实现,这样大家学习成本就高了。

  2. 标准统一了,做工具的就能使用统一标准,这样又可以方便丰富生态,不用每个渠道都去做一套适配。

以java.sql.Driver为例,JDK定义了java.sql.Driver,告诉大家要做什么,如果大家这样这样做了,用户就可以直接使用JDK提供的java.sql包中的工具就可以操作数据库了,而不用关心MySQL的这种驱动到底怎样实现,MongoDB那种驱动怎么实现。

扫描二维码关注公众号,回复: 11743545 查看本文章

有点向设计模式中中介模式,都找中介,不用关心其他。

SPI接口实现流程

  1. classpath路径中添加一个/META-INF/services目录,一般具体那个classpath目录无所谓,放在JDK的lib目录下都行,不过为了让其他人也能使用你的jar包,最好放在自己的jar包中。

  2. 在/META-INF/services目录下添加一个要实现的接口的全限定名称的文件。例如,java.sql.Driver,文件中的内容是你实现这个接口的全限定类名,例如,com.mysql.cj.jdbc.Driver。如果有多个实现类,每行一个。

  3. 实现对应的接口

spi-Driver

具体的处理逻辑在ServiceLoader这个类中:

ServiceLoader中的LazyIterator内部类的hasNextService方法,是加载配置资源文件的实现。

ServiceLoader的parseLine方法是具体解析配置文件的实现。

SPI接口提供流程

给定SPI接口,提供相应的工具类,可以参考Java的DriverManager的loadInitialDrivers方法。

dubbo与SPI

dubbo没有使用JDK的ServiceLoader,而是自己写了一个ExtensionLoader来实现相应的逻辑。

dubbo-spi

反思

我们真的有必要使用SPI么?直接使用接口,提供注册方式它不香吗?

当然这个得具体问题,具体分析。

JDK的java.sql.Driver处理数据库驱动,使用SPI方式比较恰当,因为可以屏蔽用户与三方驱动的关系,减少用户学习成本。

Dubbo使用SPI,倒不是不可以,只是个人觉得没有必要。

比如Dubbo的Filter,Filter这种非常个性化的一般都是特定实现,就是说我用我才会自己去实现,难道有第三方专门提供一些Filter,然后打个jar包给大家用?

不要说Filter,有多少大家使用的Dubbo扩展第三方jar包?

我都自己实现Filter了,当然就不用谈学习成本了,结果还非要我按规则来弄个配置文件,给个注册Filter的接口它不香么?使用注解,给一个注解工具类,它不方便么?

猜你喜欢

转载自blog.csdn.net/trayvontang/article/details/108130748