`

dubbo源码解析(1)

    博客分类:
  • java
阅读更多

Dubbo代码解析

 

    dubbo发布服务端的源码解析。

dubbo发布服务不需要集成重量级的web服务器,直接提供了com.alibaba.dubbo.container.Main进行

启动发布。

if (args == null || args.length == 0) {

                String config = ConfigUtils.getProperty(CONTAINER_KEY, loader.getDefaultExtensionName());

                args = Constants.COMMA_SPLIT_PATTERN.split(config);

            }

开始判断main函数的传入参数,在args参数为空的情况下,从部署环境中取得dubbo.container属性,

dubbo提供了configUtils的dubbo环境配置的访问工具类。

下面就是configUtils的取得属性的配置的顺序

 

        String value = System.getProperty(key);

        if (value != null && value.length() > 0) {

            return value;

        }

        Properties properties = getProperties();

        return replaceProperty(properties.getProperty(key, defaultValue), (Map)properties);

先是从取得系统属性,如果取得有效配置值则直接采用,否则去构造配置对象,从配置对象中取得配置值,

 

 

下面是构造配置对象的代码:

private static volatile Properties PROPERTIES;

    

    public static Properties getProperties() {

        if (PROPERTIES == null) {

            synchronized (ConfigUtils.class) {

                if (PROPERTIES == null) {

                    String path = System.getProperty(Constants.DUBBO_PROPERTIES_KEY);

                    if (path == null || path.length() == 0) {

                        path = System.getenv(Constants.DUBBO_PROPERTIES_KEY);

                        if (path == null || path.length() == 0) {

                            path = Constants.DEFAULT_DUBBO_PROPERTIES;

                        }

                    }

                    PROPERTIES = ConfigUtils.loadProperties(path, falsetrue);

                }

            }

        }

        return PROPERTIES;

}

采用懒加载的模式,进行构造,为了保证这段代码能在多线程下执行,运用了严格加锁的机制。先是通过寻求系统属性值dubbo.properties.file,如果存在,直接加载以此作为路径加载文件。没有设置的话就采用默认的配置文件dubbo.properties。然后就会通过先直接搜索文件系统,类路径等方式,来取得系统的配置。当然整个配置文件默认的可以没有,而且只有一个文件才会起作用。

然后从属性环境中读取到dubbo.container值,得到需要以命名方式加载哪些container

 final List<Container> containers = new ArrayList<Container>();

            for (int i = 0; i < args.length; i ++) {

                containers.add(loader.getExtension(args[i]));

            }

 

Container是接口。

dubbo中有很多被spi注释的接口。这些都是具有很强扩展能力的地方。

@SPI("spring")

public interface Container {

    

    /**

     * start.

     */

    void start();

    

    /**

     * stop.

     */

    void stop();

 

}

每个spi注解的实现类都是有扩展点加载器(ExtensionLoader)进行加载,

main类中,直接定义了一个静态变量:

 private static final ExtensionLoader<Container> loader = ExtensionLoader.getExtensionLoader(Container.class);

在加载Main类的时候,就会以Container类为参数直接加载。

下面看看getExtensionLoader函数。

在这个函数中先做Container中做有效性验证,而且判断是否被spi注解注释。进一步确认了扩展点加载器只能加载被spi注解的类。

ExtensionLoader类中存在

  private static final ConcurrentMap<Class<?>, ExtensionLoader<?>> EXTENSION_LOADERS = new ConcurrentHashMap<Class<?>, ExtensionLoader<?>>();

spi接口类和对应的加载器一一对应起来,同时提供懒加载的缓存作用。

下面是extensionloader的简单类图:

其中extensionFactory是扩展点是一个工厂类,因为扩展点实现如果依赖其他的类的话,只要,在里面依赖的对象遵从javabean方式,那么dubbo就会在环境对象池中(这里主要是spring容器以及扩展点工厂中取得依赖的对象)。

 objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());

ExtensionFactory本身就是spi扩展点类,所以它也需要ExtensionLoader进行加载。

ExtensionLoader这里用了一种变异的单例模式,因为ExtensionLoader对于每个扩展点只有一个。

ExtensionFactory的扩展实现,是通过这个spi接口对应的ExtensionLoader的对应的getAdaptiveExtension得到。

getAdaptiveExtension这个方法中,先是看是否已经创建,有直接返回,

没有的话

采用同步锁的方式去调用createAdaptiveExtension创建这个转接器对象。

下面是createAdaptiveExtension的调用序列图:

 

就是在createAdaptiveExtension中如果发现扩展点的实现类没有被加载,就会调用getExtensionClasses从三个目录中去
META-INF/dubbo/internal/META-INF/dubbo/META-INF/services/中去加载接口全称命名的配置文件。

配置文件记录的就是实现类以及该类对应的注册名。(当然也可以不提供注册名,dubbo会直接按照通过注解Extension命名,以及直接使用简单类名

加载配置文件方法loadFile中,对于每个扩展点的实现类,他都会查看这个实现类是否被Adaptive标注。当然这个函数中有些原则性的错误检测,比喻一个扩展点只能只有一个Adaptive扩展点。

其实对于一个扩展点,声明为Adaptive的往往是其他实现的集成。

所以一个扩展点在dubbo中为默认存在三种实现,Adaptivewrapped,以及normal实现。主要提供特定功能,主要是normal实现,当然wrapped的可以做响应过滤权限验证等类似aop的切面功能。Adaptive则某种意义上是集成。

 

对于扩展点实现类还支持Activate注解,这样就指明了这个扩展实现被激活的加载条件。

如果存在直接被Adaptive注解的类,这直接使用这个类。如果没有的话就动态创建java文件然后利用java编译器去运行时编译产生这个类。

最后创建完extension实现后,在方法injectExtension中实现依赖注入。

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    dubbo源码解析 1 pdf2.0

    根据给定的文件信息,以下是关于Dubbo源码解析的详细知识点: 首先,阅读Dubbo源码前需要一定的预备知识。这包括但不限于以下几点: 1. Java编程语言:掌握Java编程基础,阅读《Java编程思想》能够有助于理解源码...

    dubbo源码解析2

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

    dubbo源码解析

    本文对dubbo源码进行了深入的解析,涵盖了dubbo的架构、核心机制分析、扩展点加载流程、代理机制、远程调用流程、集群和容错处理、监控机制等多个方面。通过阅读和理解这些内容,可以更好地掌握dubbo的内部工作机制...

    dubbo源码分析pdf.zip

    《Dubbo源码分析》是一套深入探讨Apache Dubbo这一著名Java开源框架的书籍,旨在帮助开发者更好地理解和应用Dubbo。Dubbo是一个高性能、轻量级的服务治理框架,广泛应用于微服务架构中,以实现服务的发布、发现、...

    dubbo源码解析2.0.7z

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

    dubbo源码分析系列

    《Dubbo源码分析系列》是一份深入探讨Java开源框架Dubbo核心原理和技术细节的资料。Dubbo,作为阿里巴巴的一款高性能、轻量级的服务治理框架,它为分布式系统提供了服务发现、调用、负载均衡、容错等关键功能。这份...

    dubbo源码解析2.01.pdf

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

    dubbo 源码解析

    dubbo源码一览

    dubbo入门学习框架源码

    四、Dubbo源码解析 1. 远程调用(RPC):Dubbo的Remoting层处理服务间的网络通信,包括协议解析、序列化、连接管理等。Protocol接口定义了服务调用的基本操作,如refer、invoke等,而Exporter和Invoker接口则封装了...

    Dubbo源码解析

    ### Dubbo源码解析——Filter和Listener的注入过程 #### 前言 本文将深入探讨Dubbo框架中Filter和Listener的注入过程。不同于普通的概念介绍或功能概述,本文聚焦于技术实现细节,旨在帮助中高级软件开发工程师...

    dubbo源码解析(含注释)

    本代码是github下载的dubbo源码,构建好了,可直接使用,其中包含一些demo和看的过程中的一些见解(注释),还包含sentinel、ZooInspector,以及新老版本的dubbo管控台,下载下来打开可直接使用,需要安装zookeeper,...

    Dubbo 源码分析

    深入理解Dubbo的源码有助于开发者优化服务性能,解决实际问题,以及更好地定制化服务。下面,我们将详细探讨Dubbo的几个关键模块。 **1. 服务提供者(Provider)** 服务提供者是Dubbo架构中的基础组件,它负责暴露...

    dubbo源码分析

    公司同事分享的dubbo源码分析,非常好非常好非常好非常好非常好!

    dubbo 视频下载

    1. **Dubbo框架**:Dubbo是一款高性能、轻量级的Java RPC框架,由阿里巴巴开源,它提供了服务治理、监控、容错和负载均衡等功能,是企业级分布式应用服务的核心组件。学习Dubbo视频可以帮助我们深入理解微服务架构中...

Global site tag (gtag.js) - Google Analytics