(未完成)Dubbo源码分析(七):Dubbo内核实现之基于SPI思想Dubbo内核实现

SPI接口定义

定义了@SPI注解

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等等

(未完成)Dubbo源码分析(七):Dubbo内核实现之基于SPI思想Dubbo内核实现_第1张图片(未完成)Dubbo源码分析(七):Dubbo内核实现之基于SPI思想Dubbo内核实现_第2张图片


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


(未完成)Dubbo源码分析(七):Dubbo内核实现之基于SPI思想Dubbo内核实现_第3张图片




你可能感兴趣的:((未完成)Dubbo源码分析(七):Dubbo内核实现之基于SPI思想Dubbo内核实现)