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