Dubbo源码分析(6):Dubbo内核实现之基于SPI思想Dubbo内核实现

SPI接口定义 定义了@SPI注解java

package com.alibaba.dubbo.common.extension;
 
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
/**
 * 扩展点接口的标识。
 * <p />
 * 扩展点声明配置文件,格式修改。<br />
 * 以Protocol示例,配置文件META-INF/dubbo/com.xxx.Protocol内容:<br />
 * 由<br/>
 * <pre><code>com.foo.XxxProtocol
com.foo.YyyProtocol</code></pre><br/>
 * 改为使用KV格式<br/>
 * <pre><code>xxx=com.foo.XxxProtocol
yyy=com.foo.YyyProtocol
 * </code></pre>
 * <br/>
 * 缘由:<br/>
 * 当扩展点的static字段或方法签名上引用了三方库,
 * 若是三方库不存在,会致使类初始化失败,
 * Extension标识Dubbo就拿不到了,异常信息就和配置对应不起来。
 * <br/>
 * 好比:
 * Extension("mina")加载失败,
 * 当用户配置使用mina时,就会报找不到扩展点,
 * 而不是报加载扩展点失败,以及失败缘由。
 *
 * @author william.liangf
 * @author ding.lid
 * @export
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface SPI {
 
    /**
     * 缺省扩展点名。
     */
	String value() default "";
 
}

只有在接口打了@SPI注解的接口类才会去查找扩展点实现
会依次从这几个文件中读取扩展点
META-INF/dubbo/internal/ //dubbo内部实现的各类扩展都放在了这个目录了
META-INF/dubbo/
META-INF/services/
咱们以Protocol接口为例, 接口上打上SPI注解,默认扩展点名字为dubbo框架

/**
 * Protocol. (API/SPI, Singleton, ThreadSafe)
 * 
 * @author william.liangf
 */
@SPI("dubbo")
public interface Protocol {
    
    /**
     * 获取缺省端口,当用户没有配置端口时使用。
     * 
     * @return 缺省端口
     */
    int getDefaultPort();
 
    /**
     * 暴露远程服务:<br>
     * 1. 协议在接收请求时,应记录请求来源方地址信息:RpcContext.getContext().setRemoteAddress();<br>
     * 2. export()必须是幂等的,也就是暴露同一个URL的Invoker两次,和暴露一次没有区别。<br>
     * 3. export()传入的Invoker由框架实现并传入,协议不须要关心。<br>
     * 
     * @param <T> 服务的类型
     * @param invoker 服务的执行体
     * @return exporter 暴露服务的引用,用于取消暴露
     * @throws RpcException 当暴露服务出错时抛出,好比端口已占用
     */
    @Adaptive
    <T> Exporter<T> export(Invoker<T> invoker) throws RpcException;
 
    /**
     * 引用远程服务:<br>
     * 1. 当用户调用refer()所返回的Invoker对象的invoke()方法时,协议需相应执行同URL远端export()传入的Invoker对象的invoke()方法。<br>
     * 2. refer()返回的Invoker由协议实现,协议一般须要在此Invoker中发送远程请求。<br>
     * 3. 当url中有设置check=false时,链接失败不能抛出异常,并内部自动恢复。<br>
     * 
     * @param <T> 服务的类型
     * @param type 服务的类型
     * @param url 远程服务的URL地址
     * @return invoker 服务的本地代理
     * @throws RpcException 当链接服务提供方失败时抛出
     */
    @Adaptive
    <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
 
    /**
     * 释放协议:<br>
     * 1. 取消该协议全部已经暴露和引用的服务。<br>
     * 2. 释放协议所占用的全部资源,好比链接和端口。<br>
     * 3. 协议在释放后,依然能暴露和引用新的服务。<br>
     */
    void destroy();
 
}

dubbo中内置实现了各类协议如:DubboProtocol InjvmProtocolHessianProtocol WebServiceProtocol等等jvm

Dubbo默认rpc模块默认protocol实现DubboProtocol,key为dubbourl

其余协议提供方式雷同,这里不一一列举了。3d

相关文章
相关标签/搜索