写点什么

Dubbo 源码解析之 SPI(一):扩展类的加载过程(上)

  • 2020-02-06
  • 本文字数:1354 字

    阅读完需:约 4 分钟

Dubbo源码解析之SPI(一):扩展类的加载过程(上)

Dubbo 是一款开源的、高性能且轻量级的 Java RPC 框架,它提供了三大核心能力:面向接口的远程方法调用、智能容错和负载均衡,以及服务自动注册和发现。


Dubbo 最早是阿里公司内部的 RPC 框架,于 2011 年开源,之后迅速成为国内该类开源项目的佼佼者,2018 年 2 月,通过投票正式成为 Apache 基金会孵化项目。目前宜信公司内部也有不少项目在使用 Dubbo。


本系列文章通过拆解 Dubbo 源码,帮助大家了解 Dubbo,做到知其然,并且知其所以然。

一、JDK SPI

1.1 什么是 SPI?

SPI(Service Provider Interface),即服务提供方接口,是 JDK 内置的一种服务提供机制。在写程序的时候,一般都推荐面向接口编程,这样做的好处是:降低了程序的耦合性,有利于程序的扩展。


SPI 也秉承这种理念,提供了统一的服务接口,服务提供商可以各自提供自己的具体实现。大家都熟知的 JDBC 中用的就是基于这种机制来发现驱动提供商,不管是 Oracle 也好,MySQL 也罢,在编写代码时都一样,只不过引用的 jar 包不同而已。后来这种理念也被运用于各种架构之中,比如 Dubbo、Eleasticsearch。

1.2 JDK SPI 的小栗子

SPI 的实现方式是将接口实现类的全限定名配置在文件中,由服务加载器读取配置文件,加载实现类。


了解了概念后,来看一个具体的例子。


1)定义一个接口


public interface Operation {        int operate(int num1, int num2);}
复制代码


2)写两个简单的实现


public class DivisionOperation implements Operation {        public int operate(int num1, int num2) {            System.out.println("run division operation");            return num1/num2;        }}
复制代码


3)添加一个配置文件


在 ClassPath 路径下添加一个配置文件,文件名字是接口的全限定类名,内容是实现类的全限定类名,多个实现类用换行符分隔。


目录结构


1578290509268050916.png


文件内容


com.api.impl.DivisionOperationcom.api.impl.PlusOperation
复制代码


4)测试程序


public class JavaSpiTest {    @Test    public void testOperation() throws Exception {        ServiceLoader operations = ServiceLoader.load(Operation.class);        operations.forEach(item->System.out.println("result: " + item.operate(2, 2)));    } }
复制代码


5)测试结果


run division operationresult:1run plus operationresult:4
复制代码

1.3 JDK SPI 的源码分析

例子很简单,实现的话,可以大胆猜测一下,看名字“ServiceLoader”应该就是用类加载器根据接口的类型加上配置文件里的具体实现名字将实现加载了进来。


接下来通过分析源码进一步了解其实现原理。

1.3.1 ServiceLoader 类

PREFIX 定义了加载路径,reload 方法初始化了 LazyIterator,LazyIterator 是加载的核心,真正实现了加载。加载的模式从名字上就可以看出,是懒加载的模式,只有当真正调用迭代时才会加载。


1578290519778011984.png

1.3.2 hasNextService 方法

LazyIterator 中的 hasNextService 方法负责加载配置文件和解析具体的实现类名。


1578290528891044303.png

1.3.3 nextService 方法

LazyIterator 中的 nextService 方法负责用反射加载实现类。


1578290536263070478.png


看完了源码,感觉这个代码是有优化空间的,实例化所有实现其实没啥必要,一来比较耗时,二来浪费资源。Dubbo 就没有使用 Java 原生的 SPI 机制,而是对其进行了增强,使其能够更好地满足需求。


本文转载自宜信技术学院公众号。


原文链接:http://college.creditease.cn/detail/345


2020-02-06 10:311325

评论

发布
暂无评论
发现更多内容

Android程序员的Java后台学习建议,2021最新Android中级面试题目汇总解答

android 程序员 移动开发

Android篇:2019初中级Android开发社招面试解答(中,跨平台app开发框架排名

android 程序员 移动开发

Android自定义view之模仿登录界面文本输入框(华为云APP)

android 程序员 移动开发

Android自定义View之游戏摇杆键盘实现(一),android开发计算器界面

android 程序员 移动开发

Android转场动画一说,android事件分发面试

android 程序员 移动开发

android进阶篇04、MVC、MVP,腾讯大牛教你自己写Android框架

android 程序员 移动开发

【LeetCode】删除链表中的节点Java题解

Albert

算法 LeetCode 11月日更

Android网络请求心路历程(1),2021Android开发现状分析

android 程序员 移动开发

微信朋友圈的高性能复杂度分析

stars

架构训练营

Android篇:2019初中级Android开发社招面试解答(上,作为Android开发者

android 程序员 移动开发

Android网络优化攻略,简单了解一下?,图文详解

android 程序员 移动开发

android自定义View——仿九宫格解锁,kotlin缺点

android 程序员 移动开发

Android自定义View之游戏摇杆键盘实现(一)(1),全网独家首发

android 程序员 移动开发

Android达到什么水平才能顺利拿到 20k 无压力?,Android基础开发与实践

android 程序员 移动开发

重磅!四大行正在大规模内测数字货币App 可凭手机号完成转账

CECBC

Android自定义View播放Gif动画,ffmpeg音视频开发实战6下载

android 程序员 移动开发

【Flutter 专题】21 易忽略的【小而巧】的技术点汇总 (二)

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 11月日更

Android菜鸟进字节跳动,居然是看了这个,Android技术篇

android 程序员 移动开发

Android第三方库收藏汇总,移动应用开发框架

android 程序员 移动开发

Android老司机被打脸!Dialog 对应的 Context 必须是 Activity吗?

android 程序员 移动开发

Android菜鸟进字节跳动,居然是看了这个(1),kotlin单例应用

android 程序员 移动开发

Android进阶——Android跨进程通讯机制之Binder,okhttp读取信息kotlin

android 程序员 移动开发

Android系统启动流程(一)解析init进程启动过程,安卓移动开发基础案例教程

android 程序员 移动开发

Android系统架构与系统源码目录,灵魂一问-如何彻底防止APK反编译

android 程序员 移动开发

Android组件化开发的意义何在?,androidui开发框架

android 程序员 移动开发

Android网络请求心路历程,面试安卓工程师会问到那些问题

android 程序员 移动开发

Android自动化页面测速在美团的实践,百度、阿里、滴滴、新浪的面试心经总结

android 程序员 移动开发

Android自定义控件 _ 高可扩展单选按钮(再也不和产品经理吵架了)

android 程序员 移动开发

Android自定义控件(神级)+MediaRecoder录音,android开发基础应用

android 程序员 移动开发

Android超实用最全面试大纲(四),2021大厂Android知识点总结

android 程序员 移动开发

Android转战Web前端,靠着这份面试题和答案,一举拿下京东offer

android 程序员 移动开发

Dubbo源码解析之SPI(一):扩展类的加载过程(上)_区块链_郑祥斌_InfoQ精选文章