- 浏览: 77704 次
文章分类
最新评论
-
kevinflynn:
...
ThreadLocal 源码分析 -
kevinflynn:
[url=aaaa][/url]
ThreadLocal 源码分析 -
kevinflynn:
学习到了 感谢楼主。
ThreadLocal 源码分析
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;
}
}
/**
* 配置中心接口,
*/
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;
}
}
发表评论
-
dubbo-common-rpc
2020-12-30 22:46 403ApplicationModel 实例模型. ... -
dubbo-filter 源码分析
2019-12-01 23:08 466说明:这个模块的功能是缓存调用结果,但是我有一个疑问,比如说开 ... -
dubbo 监控中心源码分析
2019-11-28 00:15 534MonitorFactory 创建 Monitor 的接口 ... -
dubbo injvm 协议分析
2019-11-21 23:49 810在看 injvm 协议的时候,我们还是从 InjvmProto ... -
[dubbo] resteasy 调用流程分析
2019-11-21 00:46 740在看 dubbo rest 协议的时候,很多东西都不是很懂,特 ... -
【dubbo】基于httpclient实现rpc的思路
2019-11-18 22:05 720今天在看 dubbo http 协议的时候,发现它是使用 js ... -
dubbo http 协议分析
2019-11-13 23:30 678今天看 dubbo http 协议的时候,觉得很好玩,开始的理 ... -
dubbo remoting 层之 exchange
2019-10-31 00:38 623补充点额外知识: CompletableFuture 现在 ... -
dubbo remoting 层分析
2019-10-29 01:17 708remote 层关注 transport 和 exchange ... -
dubbo 序列化是如何封装的
2019-10-27 17:55 553dubbo 是支持多种序列化方式的,那么它就必须在此基础上做一 ... -
dubbo 线程池
2019-08-31 23:18 0dubbo 中有四个线程池: CachedThreadPoo ... -
dubbo 线程池
2019-08-31 23:18 769dubbo 中有四个线程池: CachedThreadPoo ... -
关于 dubbo 的 SpiExtensionFactory 的一点说明
2019-08-29 00:30 672关于 dubbo 的 SpiExtensionFa ...
相关推荐
《Dubbo源码分析》是一套深入探讨Apache Dubbo这一著名Java开源框架的书籍,旨在帮助开发者更好地理解和应用Dubbo。Dubbo是一个高性能、轻量级的服务治理框架,广泛应用于微服务架构中,以实现服务的发布、发现、...
《Dubbo源码分析系列》是一份深入探讨Java开源框架Dubbo核心原理和技术细节的资料。Dubbo,作为阿里巴巴的一款高性能、轻量级的服务治理框架,它为分布式系统提供了服务发现、调用、负载均衡、容错等关键功能。这份...
这部分源码展示了如何对接Dubbo的配置中心,如ZKConfigurator,实现配置的实时同步和更新。 八、异常处理与日志记录 在源码中,我们可以看到dubbo-admin如何处理各种异常情况,以及如何记录和上报日志。这部分内容...
深入源码分析,我们可以看到Dubbo如何通过Netty框架来实现异步非阻塞的网络通信,以及如何通过Hessian或Protobuf等序列化库进行数据交换。 接下来,我们关注服务注册与发现。Dubbo提供了Zookeeper、Eureka、Redis等...
本文对dubbo源码进行了深入的解析,涵盖了dubbo的架构、核心机制分析、扩展点加载流程、代理机制、远程调用流程、集群和容错处理、监控机制等多个方面。通过阅读和理解这些内容,可以更好地掌握dubbo的内部工作机制...
综上所述,通过对Dubbo源码的详细分析,我们可以了解到它不仅仅是一个简单的RPC框架,而是涵盖了服务治理、集群容错、负载均衡等多个方面的复杂系统。希望以上解析能够帮助读者更深入地理解Dubbo的内部工作原理和...
《深入剖析Dubbo 2.5.3源码》 Dubbo是一款高性能、轻量级的开源Java RPC框架,由阿里...通过对源码的分析,我们可以了解到Dubbo如何优雅地处理服务发现、调用、监控等问题,为构建大规模分布式系统提供有力的支持。
《Dubbo框架源码解析深度探索》 Dubbo,作为阿里巴巴开源的一款高性能、轻量级的服务治理框架,已经成为Java世界中分布式...Dubbo的源码阅读也是一个不断提升自身技术深度的过程,有助于成长为更优秀的Java开发者。
在深入理解Dubbo源码之前,需要掌握一系列基础知识,这将有助于更好地理解Dubbo的设计与实现。 1. **Java语言编程**:熟悉Java语言的基本语法和面向对象特性,对于理解Dubbo中的各种类、接口以及方法非常重要。 2. ...
8. **源码分析** - **ServiceConfig 和 ReferenceConfig**:分别代表服务提供者和服务消费者的配置类,用于构建服务暴露和引用的核心对象。 - **RegistryFactory 和 Registry**:负责与注册中心的交互,注册和订阅...
【标题】"dubbo应用实例源码工程"指的是一个基于Dubbo框架的示例项目,它提供了实际操作的代码,帮助开发者理解如何在项目中应用Dubbo。Dubbo是阿里巴巴开源的一个高性能、轻量级的服务治理框架,广泛应用于分布式...
通过对Dubbo源码的阅读和分析,我们可以更深入地理解服务治理的原理,学习到如何设计高可用、可扩展的微服务架构,这对于提升我们的Java编程技能和系统设计能力具有重要的实践意义。同时,Dubbo也是许多企业级项目的...
例如,当我们需要添加新的服务协议或者自定义注册中心时,可以通过实现相应的SPI接口,并按照Dubbo的规则进行配置,就能轻松完成扩展。 总的来说,Dubbo的SPI机制是其强大功能背后的关键技术之一,它不仅提供了类似...
源码分析可以帮助开发者深入理解其内部机制,提升开发和优化服务的能力。 1. **设计模式与架构** - **服务提供者(Provider)**:提供服务的模块,暴露服务接口供消费者调用。 - **服务消费者(Consumer)**:...
《Dubbo 2.0 源码解读》是一份深度剖析Dubbo核心机制和技术细节的资料,旨在帮助开发者深入理解这一著名Java微服务框架的工作原理。以下是对这份资料主要知识点的详细阐述: 1. **源码阅读路径**:源码阅读是提升...
这里将详细阐述Dubbo的核心概念、控制台的功能、源码分析的重要性,以及opensesame项目在其中的角色。 Dubbo是阿里巴巴开源的一款高性能、轻量级的Java分布式服务框架,它主要提供了服务治理、注册中心、调用链跟踪...
Dubbo是中国阿里巴巴开源的一款高性能、轻量级的Java服务治理框架,它主要专注于服务调用、服务注册与发现、负载均衡、容错以及监控等核心...同时,源码分析也是提升自身技术能力,掌握分布式系统设计原理的重要途径。
本次我们将通过分析Dubbo 2.7.2的源码,来深入了解其设计理念和实现机制,帮助开发者更好地理解和运用这个强大的工具。 一、Dubbo架构概览 Dubbo的核心架构基于服务提供者(Provider)、消费者(Consumer)、注册...