彩色科技|Dubbo自适应扩展机制

上一节提到过 , Dubbo里除了Service和Config层为API , 其它各层均为SPI 。 相比于Java中的SPI仅仅通过接口类名获取所有实现 , Dubbo的实现可以通过接口类名和key值来获取一个具体的实现 。 通过SPI机制 , Dubbo实现了面向插件编程 , 只定义了模块的接口 , 实现由各插件来完成 。
1. 使用方式1.1 Java SPI在扩展类的jar包内 , 放置扩展点配置文件META-INF/service/接口全限定名 , 内容为:扩展实现类全限定名 , 多个实现类用换行符分隔 。
如下为Mysql中Driver接口的实现:
彩色科技|Dubbo自适应扩展机制package com.mysql.jdbc;import java.sql.SQLException;public class Driver extends NonRegisteringDriver implements java.sql.Driver {... }调用时使用ServiceLoader加载所有的实现并通过循环来找到目标实现类
ServiceLoader loadedDrivers = ServiceLoader.load(Driver.class);Iterator driversIterator = loadedDrivers.iterator();try{while(driversIterator.hasNext()) {driversIterator.next();}} catch(Throwable t) {// Do nothing}1.2 Dubbo SPI拿Dubbo中Protocol接口来说 , Protocol的定义如下:
package org.apache.dubbo.rpc;import org.apache.dubbo.common.URL;import org.apache.dubbo.common.extension.Adaptive;import org.apache.dubbo.common.extension.SPI;@SPI("dubbo")public interface Protocol {int getDefaultPort();@AdaptiveExporter export(Invoker invoker) throws RpcException;@AdaptiveInvoker refer(Class type, URL url) throws RpcException;void destroy();}需要指出的是Invoker继承了Node接口 , 而Node接口提供了getUrl方法 , 既每个方法都能从入参获得URL对象 。
public interface Node {URL getUrl();boolean isAvailable();void destroy();}要求
1.接口上有org.apache.dubbo.common.extension.SPI注解 , 提供默认的实现
2.对于支持自适应扩展的方法要求方法入参能获得org.apache.dubbo.common.URL对象 , 同时方法上有org.apache.dubbo.common.extension.Adaptive注解 , Adaptive注解可以提供多个key名 , 以便从URL中获取对应key的值 , 从而匹配到对应的实现(这里Protocol比较特别 , 没有提供key名也能根据URL来动态获取实现 , 后面会说明)
3.在扩展类的jar包内 , 放置扩展点配置文件META-INF/dubbo/接口全限定名 , 内容为:配置名=扩展实现类全限定名 , 多个实现类用换行符分隔 。 如Protocol的默认实现:
彩色科技|Dubbo自适应扩展机制注意:META-INF/dubbo/internal为Dubbo内部实现的配置文件路径
调用时通过ExtensionLoader根据需要来选择具体的实现类 ,
ExtensionLoaderloader = ExtensionLoader.getExtensionLoader(Protocol.class);可选方式包括
1.选择默认的实现
Protocol protocol = loader.getDefaultExtension();2.根据指定key选择实现
Protocol protocol = loader.getExtension("dubbo");3.根据URL参数动态获取实现
Protocol protocol = loader.getAdaptiveExtension();2. Dubbo SPI 特性Dubbo对Java中的标准SPI进行了扩展增强 , 官方文档中提到其提供了如下特性: