博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Dubbo解析(一)-内核实现之SPI机制(上)
阅读量:6685 次
发布时间:2019-06-25

本文共 3178 字,大约阅读时间需要 10 分钟。

hot3.png

Dubbo采用微内核+插件的方式,使得设计优雅,扩展性强。但也给源码的学习带来了一定的困难,初看者常常迷失在找不到方法的具体实现。在学习dubbo源码前,必须要了解其内核的SPI机制.什么是SPI,它是JDK内置的一种服务发现机制,全称是Service Provider Interface(服务提供者接口),也就是寻找接口服务的提供者的一种规范。

举个例子,你在淘宝上卖东西,客户下单后要发快递,一般你会找快递公司帮你运输。快递公司有很多家,不同的快递公司提供的服务也不同,比如顺丰可能就快一点,韵达可能就慢一点。发快递就是一个接口服务,而真正的实现由不同的快递公司来完成。

定义一个发快递的接口

package com.lntea.dubbo.demo.spi;public interface Delivery {	void deliveryProduct(String productName);}

有两个不同的实现

// 顺丰package com.lntea.dubbo.demo.spi;public class ShunFengDelivery implements Delivery{	public void deliveryProduct(String productName) {		System.out.println("你的" + productName + "到家了,顺丰快递为您服务");	}}// 韵达package com.lntea.dubbo.demo.spi;public class YunDaDelivery implements Delivery{	public void deliveryProduct(String productName) {		System.out.println("你的" + productName + "到家了,韵达快递为您服务");	}}

因为快递公司是第三方,我们定义快递接口服务时,根本不知道发快递的到底是哪家公司。JDK的SPI机制就定义了一些规范,来帮助我们寻找服务的提供者实现:

  1. 在classpath的META-INF/services/目录下创建名称为服务接口的全限定名(package+className)的文件,文件编码必须为UTF-8,文件内容为服务接口实现类的全限定名,一个文件内可以定义多个实现类,按行分开即可。
  2. 服务接口实现类必须有一个无参的构造方法。
  3. 使用java.util包下的ServiceLoader类的load方法动态加载接口的实现类。

按照JDK的SPI机制完成发快递的代码

package com.lntea.dubbo.demo.spi;import java.util.Iterator;import java.util.ServiceLoader;import org.junit.Test;public class DeliveryTest {		@Test	public void testDeliveryProduct(){		String productName = "Iphone X";		delivery(productName);	}	private void delivery(String productName) {		ServiceLoader
loader = ServiceLoader.load(Delivery.class); Iterator
iterator = loader.iterator(); while(iterator.hasNext()){ Delivery delivery = iterator.next(); delivery.deliveryProduct(productName); } }}输入结果如下:你的Iphone X到家了,顺丰快递为您服务你的Iphone X到家了,韵达快递为您服务

ServiceLoader实现了Iterable接口,可以遍历每一个服务提供者,并调用它的服务。结果就是客户买了一个Iphone X, 结果你快递了两个给人。当然淘宝卖家不会这么傻,一般都会默认一家快递公司,或者客户可以指定其他的快递公司,我们就需要接口中定义一个匹配方法。

public interface Delivery {    // 公司名称是否匹配	boolean match(String companyName);	void deliveryProduct(String productName);}

那顺丰和韵达在服务实现类中就要匹配自己的公司名称

// 顺丰public class ShunFengDelivery implements Delivery{	public boolean match(String companyName) {		return "sf".equals(companyName);	}		public void deliveryProduct(String productName) {		System.out.println("你的" + productName + "到家了,顺丰快递为您服务");	}}// 韵达public class YunDaDelivery implements Delivery{	public boolean match(String companyName) {		return "yd".equals(companyName);	}		public void deliveryProduct(String productName) {		System.out.println("你的" + productName + "到家了,韵达快递为您服务");	}}

发快递的代码也需要变更

public class DeliveryTest {		@Test	public void testDeliveryProduct(){		String productName = "Iphone X";		String companyName = "sf";		delivery(companyName, productName);	}	private void delivery(String companyName, String productName) {		ServiceLoader
loader = ServiceLoader.load(Delivery.class); Iterator
iterator = loader.iterator(); while(iterator.hasNext()){ Delivery delivery = iterator.next(); // 匹配指定的快递公司 if(delivery.match(companyName)){ delivery.deliveryProduct(productName); break; } } }}输出结果:你的Iphone X到家了,顺丰快递为您服务

以上介绍了JDK的SPI机制,而Dubbo内核对于扩展点的加载方式就是从JDK的SPI机制增强而来的。那么JDK的SPI机制有什么缺点呢,Dubbo的SPI机制又增加了哪些呢,下一章见。

转载于:https://my.oschina.net/u/2377110/blog/1827861

你可能感兴趣的文章
python:使用OO和工厂模式解决问题
查看>>
C++学习-2
查看>>
SQL中查询数据表字段名称的查询语句
查看>>
关于masonry
查看>>
mysql单表导入数据,全量备份导入单表
查看>>
GAITC 2019全球人工智能技术大会(南京)
查看>>
使用gradle生成protobuf
查看>>
transition transform animate的使用
查看>>
WebService_HelloWorld
查看>>
【翻译】Ext JS最新技巧——2014-5-12
查看>>
全局临时表
查看>>
谈谈加载(Loading)的那点事
查看>>
关于nginx的Job for nginx.service failed because the control process exited with error code.错误
查看>>
微信公众平台开发(108) 微信摇一摇
查看>>
Java 函数参数传递方式详解 分类: Java Game ...
查看>>
Flex 截图 实例
查看>>
6-4 内部类
查看>>
cryptography TransformFinalBlock 返回指定长度的哈希值
查看>>
与关系型数据库相比,MongoDB的优缺点
查看>>
使用Atom编写Makedown
查看>>