概述
dubbo内核解析
- dubbo的内核
- SPI
- JDK中的SPI
- JDK中SPI的规范
- JDK中SPI的实现
- 定义SPI服务接口
- 定义服务实现类
- 按照SPI规范编写服务提供者配置文件
- 编写main方法来进行服务调用
- JDK中SPI的不足
- dubbo中的SPI
- dubbo中SPI的规范
- dubbo中SPI的使用
- 定义SPI服务接口
- 定义服务实现类
- 按照dubbo的SPI规范编写服务提供者配置文件
- 编写main方法来进行服务调用
dubbo的内核
dubbo所有功能都是基于dubbo内核之上完成的,dubbo内核由四部分构成,分别为SPI,Adaptive,Wrapper,Activate。
而dubbo的内核设计原则,也是我们所熟悉的aop,ioc与动态编译compiler,这些称之为dubbo的内核原理。
SPI
SPI,Service Provider Interface服务提供者接口,是一种服务发现机制。
SPI的存在使得服务提供者与使用者之间实现了解耦。
JDK中的SPI
JDK中SPI的规范
- 接口名:没有限制
- 实现类名:没有限制
- 提供者配置文件路径:限定为META-INF/services
- 提供者配置文件名称:接口的全限定类名
- 提供者配置文件内容:接口的所有实现类的全限定类名,一个类名占一行
JDK中SPI的实现
定义SPI服务接口
package com.demo.service;
public interface DemoService {
String hello();
}
定义服务实现类
package com.demo.service.impl;
import com.demo.service.DemoService;
public class OneDemoService implements DemoService {
public String hello() {
return "one";
}
}
package com.demo.service.impl;
import com.demo.service.DemoService;
public class TwoDemoService implements DemoService {
public String hello() {
return "two";
}
}
按照SPI规范编写服务提供者配置文件
编写main方法来进行服务调用
package com.demo.service;
import java.util.Iterator;
import java.util.ServiceLoader;
public class MainClass {
public static void main(String[] args) {
ServiceLoader<DemoService> loader = ServiceLoader.load(DemoService.class);
Iterator<DemoService> iterator = loader.iterator();
while(iterator.hasNext()) {
DemoService service = iterator.next();
System.out.println(service.hello());
}
}
}
查看一下运行结果
观察这个配置结果我们会发现,ServiceLoader方法会按照我们事先配置好的提供者配置文件来调用实现类。
JDK中SPI的不足
通过上面的例子我们可以观察出来,我们没有办法具体到调用哪一个实现类,比如我只想调用OneDemoService是做不到的
dubbo中的SPI
dubbo源码中SPI使用的相当频繁,可以说SPI是dubbo内核中的内核。
dubbo中SPI的规范
- 接口名:没有限制
- 实现类名:在接口名前添加一个用于表示自身功能的“标识前辍”字符串
- 提供者配置文件路径:在依次查找的目录为
META-INF/dubbo/internal
META-INF/dubbo
META-INF/services
这一点可以参考源码ExtensionLoader.java 631-643
// synchronized in getExtensionClasses
private Map<String, Class<?>> loadExtensionClasses() {
cacheDefaultExtensionName();
Map<String, Class<?>> extensionClasses = new HashMap<>();
loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName());
loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName().replace("org.apache", "com.alibaba"));
loadDirectory(extensionClasses, DUBBO_DIRECTORY, type.getName());
loadDirectory(extensionClasses, DUBBO_DIRECTORY, type.getName().replace("org.apache", "com.alibaba"));
loadDirectory(extensionClasses, SERVICES_DIRECTORY, type.getName());
loadDirectory(extensionClasses, SERVICES_DIRECTORY, type.getName().replace("org.apache", "com.alibaba"));
return extensionClasses;
}
- 提供者配置文件名称:接口的全限定性类名,无需扩展名
- 提供者配置文件内容:文件的内容为 key=value 形式,value 为该接口的实现类的全限类
性类名,key 可以随意,但一般为该实现类的“标识前辍”(首字母小写)。一个类名占
一行。 - 提供者加载:ExtensionLoader 类相当于 JDK SPI 中的 ServiceLoader 类,用于加载提供者
配置文件中指定的实现类,并创建相应的实例。
dubbo中SPI的使用
定义SPI服务接口
需要引用dubbo的依赖
import org.apache.dubbo.common.extension.SPI;
/**
* 该注解为标识注解,代表该类为SPI
* 且value值代表默认提供者为服务提供者文件中定义为alipay的服务实现类
*/
@SPI("alipay")
public interface Order {
void pay();
}
定义服务实现类
public class AlipayOrder implements Order {
@Override
public void pay() {
System.out.println("使用支付宝支付");
}
}
public class WechatOrder implements Order {
@Override
public void pay() {
System.out.println("使用微信支付");
}
}
按照dubbo的SPI规范编写服务提供者配置文件
编写main方法来进行服务调用
package com.dubbospi.service;
import org.apache.dubbo.common.extension.ExtensionLoader;
public class MainClass {
public static void main(String[] args) {
ExtensionLoader<Order> loader = ExtensionLoader.getExtensionLoader(Order.class);
Order order = loader.getExtension("wechat");
order.pay();
Order order1 = loader.getDefaultExtension();
order1.pay();
}
}
执行结果如下
最后
以上就是如意枕头为你收集整理的dubbo学习篇之dubbo内核解析(一)SPIdubbo的内核的全部内容,希望文章能够帮你解决dubbo学习篇之dubbo内核解析(一)SPIdubbo的内核所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复