dubbo源码实践-SPI扩展-自适应扩展机制

Posted alf_cee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dubbo源码实践-SPI扩展-自适应扩展机制相关的知识,希望对你有一定的参考价值。

目录

1 前提必备知识

2 术语定义

3 自适应扩展机制的特点

4 扩展点实践

4.1 用户自定义自适应扩展

4.2 dubbo生成自适应扩展

4 自适应扩展类的用途


1 前提必备知识

具体的使用和原理就不说了,网上有人写的挺好的了。

可以参考:

Dubbo SPI之自适应扩展机制 @Adaptive - 简书

2 术语定义

我们先统一下本文使用的术语(个人观点,有问题欢迎讨论):

1)扩展点(就是接口):一个接口,在dubbo中使用该接口,业务人员可以动态的替换相应的扩展。

2)扩展(就是实现类):扩展点对应的实现类。一个扩展点可以有多个扩展。dubbo中通过URL+自适应扩展来实现根据参数,动态选择扩展。

在本文中,扩展点等价于接口,扩展等价于实现类。

3 自适应扩展机制的特点

看过源码后,想自己总结关于自适应扩展机制的特点:

1 自适应扩展点,一个接口只能对应一个自适应扩展,其他的扩展都是实现业务功能的扩展,该类只会有一个对象被缓存到ExtensionLoader中。可以参考ExtensionLoader源码的属性cachedAdaptiveClass、cachedAdaptiveInstance。

2 ExtensionLoader允许我们自定义自适应扩展,只要在一个实现类上加上@Adaptive注解即可。参考AdaptiveCompiler类。

3 如果我们自己不定义,ExtensionLoader可以帮我们生成一个接口(该接口的方法上需要添加@Adaptive注解)的对应实现类。

4 扩展点实践

4.1 用户自定义自适应扩展

我们在一个扩展上面加上@Adaptive注解,该扩展会成为自适应扩展。

4.1.1 项目例子概述

HelloService一个接口,该接口有3个实现(两个业务相关的实现,一个自适应实现)。一个dubbo扩展配置文件,一个程序启动入口类。

HelloService接口

package org.example.test.exAdaptive;
import org.apache.dubbo.common.extension.SPI;
@SPI("father")
public interface HelloService 
    String sayHello(String name);

两个业务实现类,FatherHelloServiceImpl、MotherHelloServiceImpl。

package org.example.test.exAdaptive;

public class FatherHelloServiceImpl implements HelloService
    @Override
    public String sayHello(String name) 
        return "Father say hello to " + name;
    

--------------------------------------

package org.example.test.exAdaptive;

public class MotherHelloServiceImpl implements HelloService
    @Override
    public String sayHello(String name) 
        return "Mather say hello to " + name;
    

自适应扩展类,注意@Adaptive注解加在类上来。

package org.example.test.exAdaptive;
import org.apache.dubbo.common.extension.Adaptive;
import org.apache.dubbo.common.extension.ExtensionLoader;
/**
 * @author lihe49
 * @version 1.0
 */
@Adaptive
public class AdaptiveHelloServiceImpl implements HelloService
    @Override
    public String sayHello(String name) 
        ExtensionLoader<HelloService> loader = ExtensionLoader.getExtensionLoader(HelloService.class);
        HelloService helloService;
        if (name.equals("A"))
            helloService = loader.getExtension("father");
         else 
            helloService = loader.getExtension("mother");
        
        return helloService.sayHello(name);
    

dubbo扩展配置文件,org.example.test.exAdaptive.HelloService文件

father=org.example.test.exAdaptive.FatherHelloServiceImpl
mother=org.example.test.exAdaptive.MotherHelloServiceImpl
adaptive=org.example.test.exAdaptive.AdaptiveHelloServiceImpl

程序启动入口文件,DubboSPI_AdaptiveTest类

package org.example.test.exAdaptive;
import org.apache.dubbo.common.extension.ExtensionLoader;
import java.util.Set;

public class DubboSPI_AdaptiveTest 
    public static void main(String[] args) 
        ExtensionLoader<HelloService> extensionLoader = ExtensionLoader.getExtensionLoader(HelloService.class);
        Set<String> supportedExtensions = extensionLoader.getSupportedExtensions();
        System.out.println("HelloService的扩展为: " + supportedExtensions);
        HelloService adaptiveExtension = extensionLoader.getAdaptiveExtension();
        System.out.println("自适应类名为: " + adaptiveExtension);
    

运行结果

需要注意两点:

1)虽然有3个实现类,但是只有两个扩展。

2)自适应扩展的类名是真是的类名。

自适应扩展只能有一个有效。定义2个,最后一个生效。感兴趣的同学可以自己测试一下。

4.2 dubbo生成自适应扩展

dubbo生成自适应扩展,需要在接口的方法上添加@Adaptive注解。

这个网上例子比较多。可以参考这篇文章的demo部分。

Dubbo插件扩展机制(@Adaptive) - StrangerIt - 博客园

4 自适应扩展类的用途

自适应扩展类用途是什么呢?

答:

1)可以通过URL参数动态选择扩展。主要是dubbo自动生成扩展方式。

2)dubbo扩展类自动注入属性的时候,注入的属性实例是自适应扩展实例。

以上是关于dubbo源码实践-SPI扩展-自适应扩展机制的主要内容,如果未能解决你的问题,请参考以下文章

DUBBO源码-自适应扩展机制

Dubbo的SPI自适应扩展

Dubbo的SPI自适应扩展

dubbo源码实践-SPI扩展

java SPI 04-spi dubbo 实现源码解析

Dubbo架构设计与源码解析 服务注册