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