概述
面试官心理分析
继续深挖,前面一些基础性的东西问完了,确定你应该都ok,了解dubbo的一些基本东西,那么问个稍微难一点点的问题,就是spi,先问问你什么是spi。然后再问一下dubbo的spi是怎么实现的?其实就是看看你对dubbo的掌握程度如何。
面试题剖析
spi,简单来说,就是service provider interface,说白了是什么意思呢,比如你有个接口,现在这个接口有3个实现类,那么在系统运行的时候对这个接口到底选择哪个实现类呢?这就需要spi了,需要根据指定的配置或者是默认的配置,去找到对应的实现类加载进来,然后用这个实现类的实例对象。
举个例子:
你有一个接口A。A1、A2、A3分别是接口A的不同实现。你通过配置接口A=实现A2,那么在系统实际运行的时候,会加载你的配置,用实现A2实例化一个对象来提供服务。
spi机制一般用在哪里?插件扩展的场景,比如你开发一个给别人使用的开源框架,如果你想让别人自己写个插件,插入到你的框架里面,从而扩展某个功能,这个时候spi的思想就可以用上了。
Java spi思想的体现
spi经典的思想体现,大家平时都在用,比如jdbc。
Java定义了一套jdbc的接口,但是Java并没有提供jdbc的实现类。
但是实际上项目跑的时候,要使用jdbc接口的哪些实现类呢?一般来说,我们要根据自己使用的数据库,比如mysql,你就将mysql-jdbc-connector.jar引入进来。使用oracle,你就将oracle-jdbc-connector.jar引入进来。在系统跑的时候,碰到你使用jdbc的接口,他会在底层使用你引入的那个jar中提供的实现类。
dubbo的spi思想
dubbo也用了spi思想,不过没有jdk的spi机制,是自己实现的一套spi机制。
Protocol protocol = ExtensonLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
Protocol接口,在系统运行的时候,dubbo会判断一下应该选用这个Protocol接口的哪个实现类来实例化对象来使用。
它会去找一个你配置的Protocol,将你配置的Protocol实现类,加载到JVM中来,然后实例化对象,就用你的哪个Protocol实现类就可以了。
上面那行代码就是dubbo里大量使用的,就是对很多组件,都是保留一个接口和多个实现,然后在系统运行的时候动态根据配置去找到对应的实现类。如果你没配置,那就走默认的实现好了,没问题。
@SPI("dubbo")
public interface Protocol {
int getDefaultPort();
@Adaptive
<T> Exporter<T> export(Invoker<T> invoker) throws RpcException;
@Adaptive
<T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
void destroy();
}
在dubbo自己的jar里,在/META_INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol文件中:
dubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol
http=com.alibaba.dubbo.rpc.protocol.http.HttpProtocol
hessian=com.alibaba.dubbo.rpc.protocol.hessian.HessianProtocol
所以说,这就看到了dubbo的spi机制默认是怎么玩儿的了,起始就是Protocol接口,@SPI(“dubbo”)说的是,通过SPI机制来提供实现类,实现类是通过dubbo作为默认key去配置文件里找到的,配置文件名称与接口全限定名一样的,通过dubbo作为key可以找到默认的实现类就是com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol。
如果想要动态替换掉默认的实现类,需要使用@Adaptive接口,Protocol接口中,有两个方法加了@Adaptive注解,就是说那两个接口会被代理实现。
比如这个Protocol接口搞了两个@Adaptive注解标注了方法,在运行的时候会针对Protocol生成代理类,这个代理类的那两个方法里面会有代理代码,代理代码会在裕兴的时候动态根据url中的protocol来获取那个key,默认是dubbo,你也可以自己指定,你如果指定了别的key,那么就会获取别的实现类的实例了。
自定义dubbo的spi扩展
如何自己扩展dubbo中的组件
下面来说说怎么自己扩展dubbo的组件。
自己写个工程,要是那种可以打成jar包的,里面src/main/resources目录下,搞一个META-INF/services,里面放个文件叫:com.alibaba.dubbo.rpc.Protocol,文件里搞一个my=com.bingo.MyProtocol。
自己把jar弄到nexus私服里去。
然后自己搞一个dubbo provider工程,在这个工程里面依赖你自己搞的哪个jar,然后在spring配置文件里给个配置:
<dubbo:protocol name=“my” port=“20000”/>provider启动的时候,就会加载到我们jar包里的my=com.bingo.MyProtocol这行配置里,接着会根据你的配置使用你定义好的MyProtocol了,这个就是简单说明一下,你通过上述方式,可以替换掉大量的dubbo内部组件,就是扔个你自己的jar包,然后配置一下即可。
dubbo-spi
dubbo里面提供了大量的类似上面的扩展点,就是说,你如果要扩展一个东西,只要你自己写个jar,让你的consumer或者是provider工程,依赖你的那个jar,在你的jar里指定目录下配置好接口名称对应的文件,里面通过key=实现类。
然后对于对应的组件,类似dubbo:protocol用你的那个key对应的实现类来实现某个接口,你可以自己去扩展dubbo的各种功能,提供你自己的实现。
最后
以上就是健康鸭子为你收集整理的简述dubbo的spi思想的全部内容,希望文章能够帮你解决简述dubbo的spi思想所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复