业务云原生架构、推荐系统以及线上生活等热点方向的高可用高性能业务架构有哪些?点击了解 了解详情
写点什么

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

2020 年 2 月 06 日

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 年 2 月 06 日 10:31432

评论

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

为什么要持续学习

不在调上

十倍效率背后的管理逻辑

Ian哥

28天写作

如果生命的长度可以被改写「幻想短篇 27/28」

道伟

28天写作

你会在车里唱K吗? (28天写作 Day27/28)

mtfelix

28天写作 智能汽车 MaaS 出行方案

SpringIOC的注解开发

小马哥

Java spring 七日更

日记 2021年2月3日(周三)

Changing Lin

个人感悟 2月春节不断更

【Linux系统】常驻进程应用实践

程序员架构进阶

Linux 守护进程 七日更 28天写作 2月春节不断更

通过扫码提交信息

IT蜗壳-Tango

七日更 2月春节不断更

随心而作

青城

28天写作 2月春节不断更

常用网址

现实中游走

机器学习笔记之:Addition and Scalar Multiplication

Nydia

图解 | 原来这就是线程池

云流

架构 线程池

第四周-第一课

Geek_娴子

由孩子学会骑自行车想到

石君

日常思考 28天写作

信息茧房

lidaobing

28天写作 信息茧房

回顾与总结 | 视频号28天(28)

赵新龙

28天写作

让我们与内心聊聊,寻找一段思考发展之路。

叶小鍵

人员培养,不是捷径的捷径(下)

一笑

管理 人才培养 28天写作

Mac打开wps后风扇转的快机身发热

现实中游走

Mac cpu 100% wps 机身发热

28天瞎写的第二百三十七天:抢了HR 饭碗了吗?

树上

HR 28天写作

每个人都应该理解这三个基本的 MLOps 概念

李忠良

28天写作

Webpack | 如何提升构建速度,进行体积优化?

梁龙先森

前端工程化 webpack 28天写作 2月春节不断更

分析 BAT 互联网巨头在大数据方向布局及大数据未来发展趋势

五分钟学大数据

大数据 2月春节不断更

原子性操作类的使用

武哥聊编程

Java 多线程 原子性 28天写作

Redis缓存热点引发的思考

Java架构师迁哥

黑客练手入门| pwnable.kr—幼儿瓶—01:fd

BigYoung

黑客 安全 安全漏洞 28天写作 2月春节不断更

硬核!阿里自爆虐心万字面试手册,Github上获赞89.7K

996小迁

spring 架构 面试 程序人生 JVM

驱动力读书笔记之三

张老蔫

28天写作

思维导图整理Java并发基础

云流

Java 架构 并发

管理笔记[6]:任人唯贤、赏罚分明、任人所长

俊毅

Mybatis【18】-- Mybatis自关联多对一查询方式

秦怀杂货店

mybatis

openEuler Developer Day 2021

openEuler Developer Day 2021

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