【AICon】AI 基础设施、LLM运维、大模型训练与推理,一场会议,全方位涵盖! >>> 了解详情
写点什么

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:311197

评论

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

智能膜切机,解决手机贴膜行业难题

Geek_116789

计算机网络基础(十一)---网络层-OSPF协议

书旅

计算机网络 网络 协议栈 OSPF

什么?不写代码也能做功能开发! -RUOYI 教程二

Java_若依框架教程

Java 无代码开发 若依

云小课 | IPv4枯了,IPv6来了

华为云开发者联盟

IP 公有云 虚拟私有云 华为云 虚拟化

ARTS打卡 第10周

引花眠

ARTS 打卡计划

架构师训练营第八章-作业1

A Matt

初识分布式:MIT 6.284系列(一)

Kerwin

分布式 MIT 28天写作

技术管理者带团队的几个实用技巧

Phoenix

团队管理 企业文化 团队 价值观

JVM系列之:JIT中的Virtual Call

程序那些事

Java JVM JIT

数据人必须知道的SQL概念(A—Z)

大唐小生

sql 数据 职场成长

财务分析与主要的模型

松子(李博源)

授人以渔:stm32资料查询技巧

华为云开发者联盟

架构 armv8 芯片 华为云 二进制

程序的机器级表示-算术与逻辑运算

引花眠

计算机基础

基于 Golang的侵入式 Opentracing实现全链路追踪 ----实践篇

是老郭啊

在人工智能时代追逐的“后浪”

华为云开发者联盟

程序员 AI 开发者 技术社区 华为云

Newbe.Claptrap 框架如何实现多级生命周期控制?

newbe36524

架构 微服务 .net core ASP.NET Core

英特尔®AI计算盒参考设计发布 加速智能边缘崛起

最新动态

你问我答:微服务治理应该如何去做?

BoCloud博云

容器 微服务 PaaS API 博云

秒杀系统问题与方案设计

superman

秒杀 架构总结

《深度工作》学习笔记(3)

石云升

学习 深度工作 工作哲学

微软苏州集体抵制来自阿里、华为的跳槽者:请停止你的“奋斗逼”行为!网友:看到 955 不加班的公司名单,我酸了

程序员生活志

程序员 加班 996

第九周

hdhdh

谈一谈webpack打包

林浩

Java 大前端 webpack

系统设计系列之如何设计一个短链服务

看山

架构 面试 分布式 架构设计 短链服务

老哥,您看我这篇Java集合,还有机会评优吗?

cxuan

Java 后端

实用!一键生成数据库文档,堪称数据库界的Swagger

程序员小富

Java MySQL

Vue中使用装饰器,我是认真的

前端有的玩

Java Vue 装饰器

Android |《看完不忘系列》之okhttp

哈利迪

android

手写一个重入锁

诸葛小猿

synchronized CAS 重入锁 compareAndSwap ReentrantLock

<<前端进阶篇>> PDF 出炉了 — 「阿宝哥」,精心准备的 6 万多字 170 页的前端进阶资料

阿宝哥

大前端

飞天茅台超卖事故:Redis分布式锁请慎用!

程序员生活志

redis 分布式

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