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

相關文章
相關標籤/搜索