motan扩展机制

简介: motan第二篇,想写motan的rpc调用过程的,但项目中需要对motan进行扩展,所以本来就先记录下

motan第二篇,想写motan的rpc调用过程的,但项目中需要对motan进行扩展,所以本来就先记录下


引导


在一个框架或者在项目中提供编写一些服务时,会出现这种情况,会有一些默认的,但你知道只是很容易满足基本的个人需求,开发人员可能会实现扩展,想自己实现定义一个实现

处理方式

  1. 提供一个设置实现类的setter,开发者在初始化时调用一下
  2. 提供配置入口,给个密钥,配置上自定义类名
  3. 类似slf4j一样,提供桥接类


SPI


motan使用了spi的方式

SPI(Service Provider Interface),服务提供接口;也是一种服务发现机制

系统里抽象的各个模块,往往有很多不同的实现方案,
比如日志模块的方案,xml解析模块、jdbc模块的方案等。面向的对象的设计里,
我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码
。一旦代码里涉及具体的实现类,就违反了可拔插的原则,
如果需要替换一种实现,就需要修改代码。
为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。
java spi就是提供这样的一个机制:为某个接口寻找服务实现的机制。
有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。

SPI与API的区别

What is the difference between Service Provider Interface (SPI) and Application Programming Interface (API)?
More specifically, for Java libraries, what makes them an API and/or SPI?the API is the description of classes/interfaces/methods/... 
that you call and use to achieve a goalthe SPI is the description of classes/interfaces/methods/... 
that you extend and implement to achieve a goal
Put differently, the API tells you what a specific class/method does for you and the SPI tells you what you must do to conform.
Sometimes SPI and API overlap. 
For example in JDBC the Driver class is part of the SPI: 
If you simply want to use JDBC, you don't need to use it directly, but everyone who implements a JDBC driver must implement that class.
The Connection interface on the other hand is both SPI and API: 
You use it routinely when you use a JDBC driver and it needs to be implemented by the developer of the JDBC driver。


JDK SPI


使用jdk自带的ServiceLoader写一个示例:

一个接口

public interface Spi {    public void provide();
}

实现类

public class DefaultSpi implements Spi{    @Override
    public void provide() {
        System.out.println("默认spi实现");
    }
}

输入类

/**
 * 一个spi的demo
 *
 */
public class SpiDemoMain{
    public static void main( String[] args )
    {        ServiceLoader<Spi> spiServiceLoader = ServiceLoader.load(Spi.class);        Iterator<Spi> spiIterator = spiServiceLoader.iterator();        while ( spiIterator.hasNext()) {
            spiIterator.next().provide();
        }
    }
}

在META文件夹里面新建个服务文件夹,在services-IN文件夹里面新建一个com.jFk.spi.Spi文件

完整的代码可从https://github.com/zhuxingsheng/spidemo下载

ServiceLoader源码解析

原理很简单,一个类实现这个SPI机制

它的本源,也就是从某个地方加载服务实现类,文件名是服务接口名

定义文件的地方

private static final String PREFIX = "META-INF/services/";

类内部使用了延迟加载LazyIterator,在使用到了实现类的时候,才去实例化。

private S nextService() {            if (!hasNextService())                throw new NoSuchElementException();
            String cn = nextName;
            nextName = null;            Class<?> c = null;            try {
                c = Class.forName(cn, false, loader);
            } catch (ClassNotFoundException x) {
                fail(service,                     "Provider " + cn + " not found");
            }            if (!service.isAssignableFrom(c)) {
                fail(service,                     "Provider " + cn  + " not a subtype");
            }            try {            // 调用next方法时,才实例化
                S p = service.cast(c.newInstance());
                providers.put(cn, p);                return p;
            } catch (Throwable x) {
                fail(service,                     "Provider " + cn + " could not be instantiated",
                     x);
            }            throw new Error();          // This cannot happen
        }


莫坦斯皮


motan的spi,跟java spi差不多,但做了一些加大

先看官方文档

  1. 实现SPI扩展点接口
  2. 类添加注解 @Spi(scope = Scope.SINGLETON) //扩展形式,单例或多例 @SpiMeta(name = "motan")//name 表示扩展点的名称,根据名称加载扩展 @Activation( sequence = 100) //同类型支持扩展非生效顺序,部分扩展点。必填添加SPI实现${classpath}/MATA-INF/services/${SPI接口全名}文件添加SPI接口实现类全可参照motan-core模块/MATA-INF/services/下的配置

主要类就是com.weibo.api.motan.core.extension.ExtensionLoader 代码在https://github.com/zhuxingsheng/motan/blob/master/motan-core/src/main/java/com/weibo/api/ motan/core/extension/ExtensionLoader.java#100-99 其实很简单,需要额外的读取代码,请看懂

还有注解类

@Spi 指定类生命周期

@SpiMeta 给类一个别名,方便配置时使用

目录
相关文章
|
5天前
|
Dubbo 网络协议 Java
性能基础之常见RPC框架浅析
【4月更文挑战第23天】性能基础之常见RPC框架浅析
30 1
性能基础之常见RPC框架浅析
|
Dubbo Java 测试技术
分布式RPC框架性能大比拼 dubbo、motan、rpcx、gRPC、thrift的性能比较
Dubbo 是阿里巴巴公司开源的一个Java高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成。不过,略有遗憾的是,据说在淘宝内部,dubbo由于跟淘宝另一个类似的框架HSF(非开源)有竞争关系,导致dubbo团队已经解散(参见http://www.oschina.net/news/55059/druid-1-0-9 中的评论),反到是当当网的扩展版本仍在持续发展,墙内开花墙外香。
6832 0
|
3月前
|
XML 缓存 Dubbo
Dubbo的魔法之门:深入解析SPI扩展机制【八】
Dubbo的魔法之门:深入解析SPI扩展机制【八】
30 0
|
3月前
|
监控 负载均衡 Dubbo
Dubbo 模块探秘:深入了解每个组件的独特功能【二】
Dubbo 模块探秘:深入了解每个组件的独特功能【二】
27 0
|
10月前
|
运维 监控 Dubbo
Dubbo协议异步单一长连接原理与优势
Dubbo协议异步单一长连接原理与优势
425 0
|
12月前
|
存储 负载均衡 Kubernetes
带你读《Apache Dubbo微服务开发从入门到精通》——二、 应用级服务发现机制详解(上)
带你读《Apache Dubbo微服务开发从入门到精通》——二、 应用级服务发现机制详解(上)
94 1
|
12月前
|
负载均衡 Kubernetes Dubbo
带你读《Apache Dubbo微服务开发从入门到精通》——二、 应用级服务发现机制详解(下)
带你读《Apache Dubbo微服务开发从入门到精通》——二、 应用级服务发现机制详解(下)
104 1
|
机器学习/深度学习 负载均衡 监控
探究Dubbo的拓展机制: 上
这篇博文是我决心深度学习Dubbo框架时记录的笔记, 主题是Dubbo的拓展点, 下面的几个部分相对来说比较零散, 貌似是不和主题挂钩的 , 并且是一些很冷门的知识点 , 但是它们确实是深入学习Dubbo的前置知识
94 0
|
缓存 Dubbo Java
探究Dubbo的拓展机制: 下
承接上篇, 本篇博文的主题就是认认真真捋一捋, 看一下 Dubbo是如何实现他的IOC / AOP / 以及Dubbo SPI这个拓展点的
70 0
|
JSON Dubbo 网络协议
分布式RPC框架Dubbo实现服务治理实用示例:集成Kryo实现高速序列化,集成Hystrix实现熔断器
本文在熟悉远程RPC服务调用的基础上,详细说明了Dubbo框架实现服务治理的实用的示例,Dubbo和Kryo集成可以实现高速序列化,Dubbo和Hystrix集成可以实现服务熔断,可以在生产端和消费端使用熔断器实现服务熔断的功能,集成Hystrix的框架可以通过Hystrix仪表盘实现对远程RPC调用的服务的治理。最后重点讲述了Hystrix的相关的实用分析。通过这篇文章,可以熟悉并会使用服务的熔断机制。
300 0
分布式RPC框架Dubbo实现服务治理实用示例:集成Kryo实现高速序列化,集成Hystrix实现熔断器