• Dubbo-Adaptive实现原理


    前言

    前面我们已经分析Dubbo SPI相关的源码,看过的小伙伴相信已经知晓整个加载过程,我们也留下两个问题,今天我们先来处理下其中关于注解Adaptive的原理。

    什么是@Adaptive

    对应于Adaptive机制,Dubbo提供了一个注解@Adaptive,该注解可以用于接口的某个子类上,也可以用于接口方法上。如果用在接口的子类上,则表示Adaptive机制的实现会按照该子类的方式进行自定义实现;如果用在方法上,则表示Dubbo会为该接口自动生成一个子类,并且重写该方法,没有标注@Adaptive注解的方法将会默认抛出异常。对于第一种Adaptive的使用方式,Dubbo里只有ExtensionFactory接口使用,AdaptiveExtensionFactory的实现就使用了@Adaptive注解进行了标注,主要作用就是在获取目标对象时,分别通过ExtensionLoader和Spring容器两种方式获取,该类的实现已经在Dubbo SPI机制分析过,此篇文章关注的重点是关于@Adaptive注解修饰在接口方法的实现原理,也就是关于Dubbo SPI动态的加载扩展类能力如何实现,搞清楚Dubbo是如何在运行时动态的选择对应的扩展类来提供服务。简单一点说就是一个代理层,通过对应的参数返回对应的类的实现,运行时编译。为了更好的理解我们来写个案例:

    1. @SPI("china")
    2. public interface PersonService {
    3. @Adaptive
    4. String queryCountry(URL url);
    5. }
    6. public class ChinaPersonServiceImpl implements PersonService {
    7. @Override
    8. public String queryCountry(URL url) {
    9. System.out.println("中国人");
    10. return "中国人";
    11. }
    12. }
    13. public class EnglandPersonServiceImpl implements PersonService{
    14. @Override
    15. public String queryCountry(URL url) {
    16. System.out.println("英国人");
    17. return "英国人";
    18. }
    19. }
    20. public class Test {
    21. public static void main(String[] args) {
    22. URL url = URL.valueOf("dubbo://192.168.0.101:20880?person.service=china");
    23. PersonService service = ExtensionLoader.getExtensionLoader(PersonService.class)
    24. .getAdaptiveExtension();
    25. service.queryCountry(url);
    26. }
    27. }
    28. china=org.dubbo.spi.example.ChinaPersonServiceImpl
    29. england=org.dubbo.spi.example.EnglandPersonServiceImpl

    该案例中首先构造了一个URL对象,这个URL对象是Dubbo中进行参数传递所使用的一个基础类,在配置文件中配置的属性都会被封装到该对象中。这里我们需要注意的是我们的对象是通过一个url构造的,并且在url的最后有一个参数person.service=china,这里也就是我们所指定的使用哪种基础服务类的参数,通过指向不同的对象就可以生成对应不同的实现。关于URL部分的介绍我们在下一篇文章介绍,聊聊Dubbo中URL的使用场景有哪些。 在构造一个URL对象之后,通过getExtensionLoader(PersonService.class)方法获取了一个PersonService对应的ExtensionLoader对象,然后调用其getAdaptiveExtension()方法获取PersonService接口构造的子类实例,这里的子类实际上就是ExtensionLoader通过一定的规则为PersonService接口编写的子类代码,然后通过javassist或jdk编译加载这段代码,加载完成之后

  • 相关阅读:
    Linux Vi编辑器基础操作指南
    小说网站,小说阅读器,小说阅读网站毕业设计
    Python:实现perfect cube完全立方数算法(附完整源码)
    中文编程工具免费版下载,中文开发语言工具免费版下载
    不买后悔的阿里云服务器租用价格表_优惠活动整理_2024新版
    Sun Solaris 修改IP地址或者主机名
    再手写线程池以及性能分析
    VBA基础知识点总结
    Spring Boot 的参数校验方案
    OpenAI首席科学家:直面AGI的可能性
  • 原文地址:https://blog.csdn.net/AS011x/article/details/126745324