`

dubbo 配置中心源码分析(一)

阅读更多
Configuration 接口分析

/**
* 配置中心接口,
*/
public interface Configuration {
    /**
     * 根据给定的 key 返回对应的值.
     *
     * @param key The configuration key.
     * @return The associated string.
     */
    default String getString(String key) {
        return convert(String.class, key, null);
    }

    /**
     * 返回 key 对应的值. 如果找不到,则返回默认值.
     *
     * @param key          The configuration key.
     * @param defaultValue The default value.
     * @return The associated string if key is found and has valid
     * format, default value otherwise.
     */
    default String getString(String key, String defaultValue) {
        return convert(String.class, key, defaultValue);
    }

    /**
     * 从配置中心返回对应的值. 这是检索属性值的基本方法. 在 Configuration 接口的典型实现中,
     * 其他 get 方法(即返回特定的数据类型) 将在内部使用此方法.
     *
     * @param key property to retrieve
     * @return the value to which this configuration maps the specified key, or
     * null if the configuration contains no mapping for this key.
     */
    default Object getProperty(String key) {
        return getProperty(key, null);
    }

    /**
     * 从配置中心返回对应的 value 值. 如果配置中心不包含此 key 对应的 value,则返回默认值.
     *
     * @param key property to retrieve
     * @param defaultValue default value
     * @return the value to which this configuration maps the specified key, or default value if the configuration
     * contains no mapping for this key.
     */
    default Object getProperty(String key, Object defaultValue) {
        Object value = getInternalProperty(key);
        return value != null ? value : defaultValue;
    }

    // 待子类实现
    Object getInternalProperty(String key);

    /**
     * 检查配置中心是否包含给定的 key.
     *
     * @param key the key whose presence in this configuration is to be tested
     * @return {@code true} if the configuration contains a value for this
     * key, {@code false} otherwise
     */
    default boolean containsKey(String key) {
        return getProperty(key) != null;
    }


    // 根据给定的类型,将 key 对应的值转换为对应的类型.
    default <T> T convert(Class<T> cls, String key, T defaultValue) {
        // we only process String properties for now
        String value = (String) getProperty(key);

        if (value == null) {
            return defaultValue;
        }

        Object obj = value;
        if (cls.isInstance(value)) {
            return cls.cast(value);
        }

        if (Boolean.class.equals(cls) || Boolean.TYPE.equals(cls)) {
            obj = Boolean.valueOf(value);
        } else if (Number.class.isAssignableFrom(cls) || cls.isPrimitive()) {
            if (Integer.class.equals(cls) || Integer.TYPE.equals(cls)) {
                obj = Integer.valueOf(value);
            } else if (Long.class.equals(cls) || Long.TYPE.equals(cls)) {
                obj = Long.valueOf(value);
            } else if (Byte.class.equals(cls) || Byte.TYPE.equals(cls)) {
                obj = Byte.valueOf(value);
            } else if (Short.class.equals(cls) || Short.TYPE.equals(cls)) {
                obj = Short.valueOf(value);
            } else if (Float.class.equals(cls) || Float.TYPE.equals(cls)) {
                obj = Float.valueOf(value);
            } else if (Double.class.equals(cls) || Double.TYPE.equals(cls)) {
                obj = Double.valueOf(value);
            }
        } else if (cls.isEnum()) {
            obj = Enum.valueOf(cls.asSubclass(Enum.class), value);
        }

        return cls.cast(obj);
    }


}


ConfigurationListener 接口

/**
* 配置侦听器,将在配置侦听更改时得到通知.
*/
public interface ConfigurationListener {

    /**
     * 侦听器回调方法. 一旦侦听器的配置发生任何更改,侦听器就会通过此方法得到通知.
     *
     * @param event config change event
     */
    void process(ConfigChangeEvent event);
}

DynamicConfiguration 接口

/**
* 动态配置
*
* 从框架内部的使用场景来看,主要有三种方法:
* 1.getConfig 从配置中心获取管理规则或单个配置项.
* 2.getConfigFile 在启动时从配置中心获取配置文件
* 3.addListener/removeListener 为需要监视的治理规则或配置项添加或删除侦听器.
*/
public interface DynamicConfiguration extends Configuration {
    String DEFAULT_GROUP = "dubbo";

    /**
     * {@link #addListener(String, String, ConfigurationListener)}
     *
     * @param key      the key to represent a configuration
     * @param listener configuration listener
     */
    default void addListener(String key, ConfigurationListener listener) {
        addListener(key, DEFAULT_GROUP, listener);
    }


    /**
     * {@link #removeListener(String, String, ConfigurationListener)}
     *
     * @param key      the key to represent a configuration
     * @param listener configuration listener
     */
    default void removeListener(String key, ConfigurationListener listener) {
        removeListener(key, DEFAULT_GROUP, listener);
    }

    /**
     * Register a configuration listener for a specified key
     * The listener only works for service governance purpose, so the target group would always be the value user
     * specifies at startup or 'dubbo' by default. This method will only register listener, which means it will not
     * trigger a notification that contains the current value.
     *
     * @param key      the key to represent a configuration
     * @param group    the group where the key belongs to
     * @param listener configuration listener
     */
    void addListener(String key, String group, ConfigurationListener listener);

    /**
     * Stops one listener from listening to value changes in the specified key.
     *
     * @param key      the key to represent a configuration
     * @param group    the group where the key belongs to
     * @param listener configuration listener
     */
    void removeListener(String key, String group, ConfigurationListener listener);

    /**
     * Get the governance rule mapped to the given key and the given group
     *
     * @param key   the key to represent a configuration
     * @param group the group where the key belongs to
     * @return target configuration mapped to the given key and the given group
     */
    default String getRule(String key, String group) {
        return getRule(key, group, -1L);
    }

    /**
     * Get the governance rule mapped to the given key and the given group. If the
     * rule fails to return after timeout exceeds, IllegalStateException will be thrown.
     *
     * @param key     the key to represent a configuration
     * @param group   the group where the key belongs to
     * @param timeout timeout value for fetching the target config
     * @return target configuration mapped to the given key and the given group, IllegalStateException will be thrown
     * if timeout exceeds.
     */
    String getRule(String key, String group, long timeout) throws IllegalStateException;

    /**
     * This method are mostly used to get a compound config file, such as a complete dubbo.properties file.
     * Also {@see #getConfig(String, String)}
     */
    default String getProperties(String key, String group) throws IllegalStateException {
        return getProperties(key, group, -1L);
    }

    /**
     * This method are mostly used to get a compound config file, such as a complete dubbo.properties file.
     * Also {@see #getConfig(String, String, long)}
     */
    String getProperties(String key, String group, long timeout) throws IllegalStateException;

    /**
     * Find DynamicConfiguration instance
     *
     * @return DynamicConfiguration instance
     */
    static DynamicConfiguration getDynamicConfiguration() {
        Optional<Configuration> optional = Environment.getInstance().getDynamicConfiguration();
        return (DynamicConfiguration) optional.orElseGet(() -> getExtensionLoader(DynamicConfigurationFactory.class)
                .getDefaultExtension()
                .getDynamicConfiguration(null));
    }

     /**
     * The format is '{interfaceName}:[version]:[group]'
     *
     * @return
     */
     static String getRuleKey(URL url) {
        return url.getColonSeparatedKey();
    }
}

DynamicConfigurationFactory 接口

定义了获取 DynamicConfiguration 的接口.

ConfigChangeType 枚举

定义了对配置项的操作,比如说新增、修改和删除.

ConfigChangeEvent 定义了对 Config 操作时产生的事件(观察者模式),最重要的就是 configType 这个属性值.

public class ConfigChangeEvent {
    private final String key;

    private final String value;
    private final ConfigChangeType changeType;

    public ConfigChangeEvent(String key, String value) {
        this(key, value, ConfigChangeType.MODIFIED);
    }

    public ConfigChangeEvent(String key, String value, ConfigChangeType changeType) {
        this.key = key;
        this.value = value;
        this.changeType = changeType;
    }

    public String getKey() {
        return key;
    }

    public String getValue() {
        return value;
    }

    public ConfigChangeType getChangeType() {
        return changeType;
    }

    @Override
    public String toString() {
        return "ConfigChangeEvent{" +
                "key='" + key + '\'' +
                ", value='" + value + '\'' +
                ", changeType=" + changeType +
                '}';
    }
}

AbstractDynamicConfigurationFactory 实现了 DynamicConfigurationFactory 的骨架,保证获取 DynamicConfiguration 是线程安全的.

NopDynamicConfiguration 实现的是一个没有任何操作的配置中心,为默认实现.

/**
* {@link DynamicConfiguration} 的默认扩展名. 如果用户未指定配置中心,或指定的配置扩展名无效,则默认为该配置中心.
*/
public class NopDynamicConfiguration implements DynamicConfiguration {

    public NopDynamicConfiguration(URL url) {
        // no-op
    }


    @Override
    public Object getInternalProperty(String key) {
        return null;
    }

    @Override
    public void addListener(String key, String group, ConfigurationListener listener) {
        // no-op
    }

    @Override
    public void removeListener(String key, String group, ConfigurationListener listener) {
        // no-op
    }

    @Override
    public String getRule(String key, String group, long timeout) throws IllegalStateException {
        return null;
    }

    @Override
    public String getProperties(String key, String group, long timeout) throws IllegalStateException {
        return null;
    }
}

0
1
分享到:
评论

相关推荐

    dubbo源码分析pdf.zip

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

    dubbo源码分析系列

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

    dubbo-admin源码

    这部分源码展示了如何对接Dubbo的配置中心,如ZKConfigurator,实现配置的实时同步和更新。 八、异常处理与日志记录 在源码中,我们可以看到dubbo-admin如何处理各种异常情况,以及如何记录和上报日志。这部分内容...

    dubbo的源码分析

    深入源码分析,我们可以看到Dubbo如何通过Netty框架来实现异步非阻塞的网络通信,以及如何通过Hessian或Protobuf等序列化库进行数据交换。 接下来,我们关注服务注册与发现。Dubbo提供了Zookeeper、Eureka、Redis等...

    dubbo源码解析

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

    dubbo源码解析2

    综上所述,通过对Dubbo源码的详细分析,我们可以了解到它不仅仅是一个简单的RPC框架,而是涵盖了服务治理、集群容错、负载均衡等多个方面的复杂系统。希望以上解析能够帮助读者更深入地理解Dubbo的内部工作原理和...

    dubbo-2.5.3源码

    《深入剖析Dubbo 2.5.3源码》 Dubbo是一款高性能、轻量级的开源Java RPC框架,由阿里...通过对源码的分析,我们可以了解到Dubbo如何优雅地处理服务发现、调用、监控等问题,为构建大规模分布式系统提供有力的支持。

    dubbo入门学习框架源码

    《Dubbo框架源码解析深度探索》 Dubbo,作为阿里巴巴开源的一款高性能、轻量级的服务治理框架,已经成为Java世界中分布式...Dubbo的源码阅读也是一个不断提升自身技术深度的过程,有助于成长为更优秀的Java开发者。

    dubbo2.0-源码阅读

    在深入理解Dubbo源码之前,需要掌握一系列基础知识,这将有助于更好地理解Dubbo的设计与实现。 1. **Java语言编程**:熟悉Java语言的基本语法和面向对象特性,对于理解Dubbo中的各种类、接口以及方法非常重要。 2. ...

    dubbo 分布式搭建源码

    8. **源码分析** - **ServiceConfig 和 ReferenceConfig**:分别代表服务提供者和服务消费者的配置类,用于构建服务暴露和引用的核心对象。 - **RegistryFactory 和 Registry**:负责与注册中心的交互,注册和订阅...

    dubbo应用实例源码工程

    【标题】"dubbo应用实例源码工程"指的是一个基于Dubbo框架的示例项目,它提供了实际操作的代码,帮助开发者理解如何在项目中应用Dubbo。Dubbo是阿里巴巴开源的一个高性能、轻量级的服务治理框架,广泛应用于分布式...

    dubbo-master源码

    通过对Dubbo源码的阅读和分析,我们可以更深入地理解服务治理的原理,学习到如何设计高可用、可扩展的微服务架构,这对于提升我们的Java编程技能和系统设计能力具有重要的实践意义。同时,Dubbo也是许多企业级项目的...

    Dubbo源码分析之SPI

    例如,当我们需要添加新的服务协议或者自定义注册中心时,可以通过实现相应的SPI接口,并按照Dubbo的规则进行配置,就能轻松完成扩展。 总的来说,Dubbo的SPI机制是其强大功能背后的关键技术之一,它不仅提供了类似...

    dubbo2.0源码解读

    《Dubbo 2.0 源码解读》是一份深度剖析Dubbo核心机制和技术细节的资料,旨在帮助开发者深入理解这一著名Java微服务框架的工作原理。以下是对这份资料主要知识点的详细阐述: 1. **源码阅读路径**:源码阅读是提升...

    apache dubbo 3.0.7源码

    源码分析可以帮助开发者深入理解其内部机制,提升开发和优化服务的能力。 1. **设计模式与架构** - **服务提供者(Provider)**:提供服务的模块,暴露服务接口供消费者调用。 - **服务消费者(Consumer)**:...

    dubbo-控制台使用源码

    这里将详细阐述Dubbo的核心概念、控制台的功能、源码分析的重要性,以及opensesame项目在其中的角色。 Dubbo是阿里巴巴开源的一款高性能、轻量级的Java分布式服务框架,它主要提供了服务治理、注册中心、调用链跟踪...

    Dubbo 源码分析

    Dubbo是中国阿里巴巴开源的一款高性能、轻量级的Java服务治理框架,它主要专注于服务调用、服务注册与发现、负载均衡、容错以及监控等核心...同时,源码分析也是提升自身技术能力,掌握分布式系统设计原理的重要途径。

    dubbo-dubbo-2.7.2源码

    本次我们将通过分析Dubbo 2.7.2的源码,来深入了解其设计理念和实现机制,帮助开发者更好地理解和运用这个强大的工具。 一、Dubbo架构概览 Dubbo的核心架构基于服务提供者(Provider)、消费者(Consumer)、注册...

Global site tag (gtag.js) - Google Analytics