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 convert(Class 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 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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值