文章插图
Dubbo里除了Service和Config层为API , 其它各层均为SPI 。相比于JAVA中的SPI仅仅通过接口类名获取所有实现 , Dubbo的实现可以通过接口类名和key值来获取一个具体的实现 。通过SPI机制 , Dubbo实现了面向插件编程 , 只定义了模块的接口 , 实现由各插件来完成 。
1. 使用方式1.1 Java SPI在扩展类的jar包内 , 放置扩展点配置文件META-INF/service/接口全限定名 , 内容为:扩展实现类全限定名 , 多个实现类用换行符分隔 。
如下为MySQL中Driver接口的实现:
文章插图
package com.mysql.jdbc;import java.sql.SQLException;public class Driver extends NonRegisteringDriver implements java.sql.Driver {... }
调用时使用ServiceLoader加载所有的实现并通过循环来找到目标实现类ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);Iterator<Driver> driversIterator = loadedDrivers.iterator();try{while(driversIterator.hasNext()) {driversIterator.next();}} catch(Throwable t) {// Do nothing}
1.2 Dubbo SPI拿Dubbo中Protocol接口来说 , Protocol的定义如下:package org.Apache.dubbo.rpc;import org.apache.dubbo.common.URL;import org.apache.dubbo.common.extension.Adaptive;import org.apache.dubbo.common.extension.SPI;@SPI("dubbo")public interface Protocol {int getDefaultPort();@Adaptive<T> Exporter<T> export(Invoker<T> invoker) throws RpcException;@Adaptive<T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;void destroy();}
需要指出的是Invoker继承了Node接口 , 而Node接口提供了getUrl方法 , 既每个方法都能从入参获得URL对象 。public interface Node {URL getUrl();boolean isAvailable();void destroy();}
要求1.接口上有org.apache.dubbo.common.extension.SPI注解 , 提供默认的实现
2.对于支持自适应扩展的方法要求方法入参能获得org.apache.dubbo.common.URL对象 , 同时方法上有org.apache.dubbo.common.extension.Adaptive注解 , Adaptive注解可以提供多个key名 , 以便从URL中获取对应key的值 , 从而匹配到对应的实现(这里Protocol比较特别 , 没有提供key名也能根据URL来动态获取实现 , 后面会说明)
3.在扩展类的jar包内 , 放置扩展点配置文件META-INF/dubbo/接口全限定名 , 内容为:配置名=扩展实现类全限定名 , 多个实现类用换行符分隔 。如Protocol的默认实现:
文章插图
推荐阅读
- 自媒体时代,如何通过流量,将自己的爱好,知识和习惯变现
- 自费社保一年需交多少?
- 完璧归赵的典故和以下 完璧归赵出自哪个时期及其典故
- 老曼峨茶山在哪里,你喝的茶来自哪儿老曼峨
- 老中医自制减肥茶,自制消脂减肥茶
- 运动|曝胖猴仔被训练营“扫地出门”,600W打水漂,网友:自己作的
- 戒不掉的茶瘾,净心自悟
- 路由器怎么自动获取IPv6地址?
- python爬取自如网房源信息
- Python自建免费HTTP服务器,无公网IP也能远程访问