`
LoveLZY
  • 浏览: 58103 次
  • 性别: Icon_minigender_1
博客专栏
Group-logo
从零编写RPC框架
浏览量:0
社区版块
存档分类
最新评论

dubbo源码研究之extension模块

阅读更多
   dubbo的扩展采用spi机制实现,spi(Service Provider Interface)是指一些提供给你继承、扩展,完成自定义功能的类、接口或者方法。spi把控制权利交个调用方,调用方来决定使用该spi的哪个实现。
   dubbo扩展机制的核心类是ExtensionLoader,该类通过静态方法getExtensionLoader获取一个指定接口的ExtensionLoader实例。
 
    @SuppressWarnings("unchecked")
    public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
        if (type == null)
            throw new IllegalArgumentException("Extension type == null");
        if(!type.isInterface()) {
            throw new IllegalArgumentException("Extension type(" + type + ") is not interface!");
        }
        if(!withExtensionAnnotation(type)) {
            throw new IllegalArgumentException("Extension type(" + type + 
                    ") is not extension, because WITHOUT @" + SPI.class.getSimpleName() + " Annotation!");
        }
        
        ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
        if (loader == null) {
            EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));
            loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
        }
        return loader;
    }


   该方法要求通过spi实现的接口上必须包含@spi注解,并且一个接口的ExtensionLoader是唯一的,保存在静态容器EXTENSION_LOADERS(ConcurrentHashMap)中。
   ExtensionLoader提供实例方法getExtension获取该接口的具体实现。
 
  	public T getExtension(String name) {
		if (name == null || name.length() == 0)
		    throw new IllegalArgumentException("Extension name == null");
		if ("true".equals(name)) {
		    return getDefaultExtension();
		}
		Holder<Object> holder = cachedInstances.get(name);
		if (holder == null) {
		    cachedInstances.putIfAbsent(name, new Holder<Object>());
		    holder = cachedInstances.get(name);
		}
		Object instance = holder.get();
		if (instance == null) {
		    synchronized (holder) {
	            instance = holder.get();
	            if (instance == null) {
	                instance = createExtension(name);
	                holder.set(instance);
	            }
	        }
		}
		return (T) instance;
	}


  具体流程如下



  该方法通过大量缓存容器来优化性能,并且每个扩展点都是单例存在,所以扩展dubbo框架的时候要注意该扩展点的线程安全性。
  ExtensionFactory为spi接口实现实例在注入属性(injectExtension)时提供注入的属性.

  该工厂有三个实现,分别支持从spring ,spi,Adaptive里面获取对象,注入Extension对象中。

 

   

  • 大小: 36.6 KB
  • 大小: 174.5 KB
分享到:
评论

相关推荐

    dubbo源码解析2

    ### Dubbo源码解析2 #### 一、源码阅读路径 在开始深入解析Dubbo源码之前,首先需要明确的是,Dubbo虽然代码量不算庞大,但是它涉及的技术领域非常广泛,对于初学者来说,可能需要具备一定的前置知识才能更好地...

    dubbo源码解析2.0.7z

    《Dubbo源码解析2.0》是一份深入剖析阿里巴巴开源框架Dubbo核心机制的资料,专注于2.0版本的源代码分析。Dubbo作为Java领域最知名的分布式服务框架之一,其设计理念、实现原理以及在实际应用中的优化策略都是开发者...

    dubbo源码解析2.01.pdf

    ### Dubbo源码解析知识点概览 #### 一、Dubbo简介与背景 - **背景**:Apache Dubbo是一款高性能、轻量级的开源服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。Dubbo版本2.01在...

    dubbo-2.6.0

    《Dubbo 2.6.0 源码解析与技术深度探讨》 Dubbo,作为阿里巴巴开源的一款高性能、轻量级的Java服务框架,深受广大开发者喜爱。...无论是对于初学者还是高级开发者,深入研究Dubbo源码都将是一次宝贵的学习经历。

    java实现验证码源码-dubbo-go:ApacheDubbo的Go实现

    Dubbo(包括协议层、注册层、集群层、配置层等)架构,这个架构的优点是:你可以用自己的方式实现这些分层接口,通过调用extension的'extension.SetXXX'覆盖dubbo-go的默认实现,无需修改源码即可完成你的特殊需求。...

    Sentinel 原理-全解析1

    `sentinel-extension`扩展模块对DataSource进行了扩展,而`sentinel-adapter`适配器模块则实现了对Servlet、Spring Cloud、Dubbo、gRPC等常见框架的适配。 通过分析Sentinel的样例代码,例如`FlowQpsDemo`,我们...

    Sentinel-master-1.7.2.zip

    - `extension`:扩展模块,包含各种扩展点,如数据源扩展、适配器扩展等。 - `example`:示例代码,展示了如何在实际项目中使用 Sentinel。 - `server`:Sentinel 服务器端的核心组件。 - `transport`:网络通信模块...

    大厂必学BAT面试题汇总及详解

    JVM中的ClassLoader有 Bootstrap ClassLoader、Extension ClassLoader、Application ClassLoader等,它们遵循双亲委派模型,确保类加载的唯一性。在必要时,我们可以打破双亲委派模型,自定义类加载器。 【Java扩展...

    20-BAT面试题汇总及详解(进大厂必看).docx

    JVM有多个类加载器,如Bootstrap ClassLoader、Extension ClassLoader和App ClassLoader,它们遵循双亲委派模型,即先由父类加载器尝试加载,失败后再由子类加载器加载。双亲委派模型能避免类的重复加载,保持类的...

Global site tag (gtag.js) - Google Analytics