1. 环境搭建
-
代码已经上传至 https://github.com/masteryourself/dubbo ,分支名称是
masteryourself-2.7.3-release
-
provider 是
dubbo-demo-xml-provider
工程,启动类是Application
-
consumer 是
dubbo-demo-xml-consumer
工程,启动类是Application
2. 源码解析
2.1 流程预览
2.1.1 关于 getExtensionLoader() 方法
2.1.2 关于 getExtension() 方法
2.1.3 整体流程预览
// 1. 从 【ServiceConfig】 的静态变量开始
private static final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension() ->
// 获取 【Protocol】 的 ExtensionLoader
org.apache.dubbo.common.extension.ExtensionLoader#getExtensionLoader ->
// 初始化 【ExtensionLoader】,调用 ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension() 方法
org.apache.dubbo.common.extension.ExtensionLoader#<init> ->
// 获取 【ExtensionFactory】 的动态代理实现
org.apache.dubbo.common.extension.ExtensionLoader#getAdaptiveExtension
// 1.1 获取 【ExtensionFactory】 的动态代理类,调用 newInstance() 方法初始化实例
org.apache.dubbo.common.extension.ExtensionLoader#createAdaptiveExtension
// 1.1.1 获取 【ExtensionFactory】 的动态代理类
org.apache.dubbo.common.extension.ExtensionLoader#getAdaptiveExtensionClass
// 1.1.1.1 初始化 【ExtensionFactory】 接口对应的所有 Extension
org.apache.dubbo.common.extension.ExtensionLoader#getExtensionClasses ->
// 1.1.1.1.1(*) 解析 Dubbo 的 spi,查找 【META-INF/dubbo/internal/】、【META-INF/dubbo/】、【META-INF/services/】 三个目录下的接口文件
org.apache.dubbo.common.extension.ExtensionLoader#loadExtensionClasses
// 1.1.1.1.1.1 解析类上的 @SPI 注解,把 value 取出,缓存在 cachedDefaultName 属性中
org.apache.dubbo.common.extension.ExtensionLoader#cacheDefaultExtensionName
// 1.1.1.1.1.2 拼装接口文件路径,解析文件内容
org.apache.dubbo.common.extension.ExtensionLoader#loadDirectory ->
// 循环解析每一行内容
org.apache.dubbo.common.extension.ExtensionLoader#loadResource
// 1.1.1.1.1.2.1(*) 解析具体类
org.apache.dubbo.common.extension.ExtensionLoader#loadClass
// 1.1.1.1.1.2.1.1 如果类上有 @Adaptive 注解,则把这个类作为动态代理类赋值给 【cachedAdaptiveClass】
org.apache.dubbo.common.extension.ExtensionLoader#cacheAdaptiveClass
// 1.1.1.1.1.2.1.2 如果是 wrapper 类(判断依据是:是否有以这个接口为参数的构造方法),存储到 【cachedWrapperClasses】 set 集合中,因此是无序的
org.apache.dubbo.common.extension.ExtensionLoader#cacheWrapperClass
// 1.1.1.1.1.2.1.3 如果不是上述两种,则存储到 【cachedActivates】 map 集合中
org.apache.dubbo.common.extension.ExtensionLoader#cacheActivateClass
// 1.1.1.2 如果所有实现类都没有 @Adaptive 注解,那么就会动态创建代理类,然后赋值给 【cachedAdaptiveClass】
// 代理类类名规则为:接口名+$Adaptive,如 【ProxyFactory$Adaptive】
org.apache.dubbo.common.extension.ExtensionLoader#createAdaptiveExtensionClass
// 1.1.1.2.1 为接口生成动态代理代码
org.apache.dubbo.common.extension.AdaptiveClassCodeGenerator#generate
// 1.1.1.2.2 把生成的代码编译后,用 classLoader 加载
org.apache.dubbo.common.compiler.Compiler#compile
// 1.1.2 调用 newInstance() 方法初始化 【AdaptiveExtensionFactory】
// 在构造方法里,会获取 ExtensionFactory 的所有 Extension 赋值给 factories 属性,这里有 【SpiExtensionFactory】 和 【SpringExtensionFactory】 两个
org.apache.dubbo.common.extension.factory.AdaptiveExtensionFactory#<init>
// 1.1.2.1 获取 name 对应的 Extension,分别为 【spi】 和 【spring】
org.apache.dubbo.common.extension.ExtensionLoader#getExtension ->
// 1.1.2.1.1(*) 创建 Extension,这里会循环用 wrapper 类包装
org.apache.dubbo.common.extension.ExtensionLoader#createExtension
// 1.1.2.1.1.1(*) 对 set 开头的方法进行自动注入,wrapper 类也会调用此方法进行自动注入
org.apache.dubbo.common.extension.ExtensionLoader#injectExtension
// 1.1.2.1.1.1.1(*) 先后从 【SpiExtensionFactory】、【SpringExtensionFactory】 中获取对应的值
org.apache.dubbo.common.extension.factory.AdaptiveExtensionFactory#getExtension
// 1.1.2.1.1.1.1.1(*) 获取接口对应的 ExtensionLoader,返回动态代理实现
org.apache.dubbo.common.extension.factory.SpiExtensionFactory#getExtension
// 1.1.2.1.1.1.1.2(*) 在 Spring 中:先根据名称获取,找不到再根据类型获取
org.apache.dubbo.config.spring.extension.SpringExtensionFactory#getExtension
// 1.1.3 调用 injectExtension() 方法完成自动注入
org.apache.dubbo.common.extension.ExtensionLoader#injectExtension
2.2 流程详解
2.2.1 ExtensionLoader#loadExtensionClasses(1.1.1.1.1)
org.apache.dubbo.common.extension.ExtensionLoader
private Map<String, Class<?>> loadExtensionClasses() {
// 解析类上的 @SPI 注解,把 value 取出,缓存在 cachedDefaultName 属性中
cacheDefaultExtensionName();
Map<String, Class<?>> extensionClasses = new HashMap<>();
// 读取 META-INF/dubbo/internal/ 路径
loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName());
loadDirectory(extensionClasses, DUBBO_INTERNAL_DIRECTORY, type.getName().replace("org.apache", "com.alibaba"));
// 读取 META-INF/dubbo/ 路径
loadDirectory(extensionClasses, DUBBO_DIRECTORY, type.getName());
loadDirectory(extensionClasses, DUBBO_DIRECTORY, type.getName().replace("org.apache", "com.alibaba"));
// 读取 META-INF/services/ 路径
loadDirectory(extensionClasses, SERVICES_DIRECTORY, type.getName());
loadDirectory(extensionClasses, SERVICES_DIRECTORY, type.getName().replace("org.apache", "com.alibaba"));
return extensionClasses;
}
2.2.2 ExtensionLoader#loadClass(1.1.1.1.1.2.1)
org.apache.dubbo.common.extension.ExtensionLoader
private void loadClass(Map<String, Class<?>> extensionClasses, java.net.URL resourceURL, Class<?> clazz, String name) throws NoSuchMethodException {
// 判断是不是接口的实现类,不是就直接报错
if (!type.isAssignableFrom(clazz)) {
throw new IllegalStateException("Error occurred when loading extension class (interface: " +
type + ", class line: " + clazz.getName() + "), class "
+ clazz.getName() + " is not subtype of interface.");
}
// 如果类上有 @Adaptive 注解,则赋值给 【cachedAdaptiveClass】
if (clazz.isAnnotationPresent(Adaptive.class)) {
cacheAdaptiveClass(clazz);
// 如果是 wrapper 类(判断依据是:是否有以这个接口为参数的构造方法),存储到 【cachedWrapperClasses】 set 集合中,因此 wrapper 是无序的
} else if (isWrapperClass(clazz)) {
cacheWrapperClass(clazz);
} else {
// 如果不是上述两种
clazz.getConstructor();
if (StringUtils.isEmpty(name)) {
name = findAnnotationName(clazz);
if (name.length() == 0) {
throw new IllegalStateException("No such extension name for the class " + clazz.getName() + " in the config " + resourceURL);
}
}
String[] names = NAME_SEPARATOR.split(name);
if (ArrayUtils.isNotEmpty(names)) {
// 存储到 【cachedActivates】 map 集合中
cacheActivateClass(clazz, names[0]);
for (String n : names) {
cacheName(clazz, n);
saveInExtensionClass(extensionClasses, clazz, name);
}
}
}
}
2.2.3 ExtensionLoader#createExtension(1.1.2.1.1)
org.apache.dubbo.common.extension.ExtensionLoader
private T createExtension(String name) {
...
try {
...
// 自动注入,对 set 开头的方法进行自动注入
injectExtension(instance);
Set<Class<?>> wrapperClasses = cachedWrapperClasses;
// 获取所有的 wrapper 类
if (CollectionUtils.isNotEmpty(wrapperClasses)) {
for (Class<?> wrapperClass : wrapperClasses) {
// 循环使用 wrapper 类包装,wrapper 类也会调用 injectExtension() 方法完成自动注入
instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
}
}
// 返回循环包装后的实例
return instance;
} catch (Throwable t) {
throw new IllegalStateException("Extension instance (name: " + name + ", class: " +
type + ") couldn't be instantiated: " + t.getMessage(), t);
}
}
2.2.4 ExtensionLoader#injectExtension(1.1.2.1.1.1)
org.apache.dubbo.common.extension.ExtensionLoader
private T injectExtension(T instance) {
try {
if (objectFactory != null) {
for (Method method : instance.getClass().getMethods()) {
if (isSetter(method)) {
/**
* Check {@link DisableInject} to see if we need auto injection for this property
*/
if (method.getAnnotation(DisableInject.class) != null) {
continue;
}
Class<?> pt = method.getParameterTypes()[0];
if (ReflectUtils.isPrimitives(pt)) {
continue;
}
try {
String property = getSetterProperty(method);
Object object = objectFactory.getExtension(pt, property);
if (object != null) {
method.invoke(instance, object);
}
} catch (Exception e) {
logger.error("Failed to inject via method " + method.getName()
+ " of interface " + type.getName() + ": " + e.getMessage(), e);
}
}
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return instance;
}
2.2.5 AdaptiveExtensionFactory#getExtension(1.1.2.1.1.1.1)
org.apache.dubbo.common.extension.factory.AdaptiveExtensionFactory
public <T> T getExtension(Class<T> type, String name) {
// 先后从【SpiExtensionFactory】、【SpringExtensionFactory】 中获取对应的值
for (ExtensionFactory factory : factories) {
T extension = factory.getExtension(type, name);
// 如果找到值就直接返回
if (extension != null) {
return extension;
}
}
return null;
}
2.2.6 SpiExtensionFactory#getExtension(1.1.2.1.1.1.1.1)
org.apache.dubbo.common.extension.factory.SpiExtensionFactory
public <T> T getExtension(Class<T> type, String name) {
// 如果自动注入的值是接口且有 @SPI 注解
if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
// 获取接口对应的 ExtensionLoader
ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);
if (!loader.getSupportedExtensions().isEmpty()) {
// 返回动态代理实现
return loader.getAdaptiveExtension();
}
}
return null;
}
2.2.7 SpringExtensionFactory#getExtension(1.1.2.1.1.1.1.2)
org.apache.dubbo.config.spring.extension.SpringExtensionFactory
public <T> T getExtension(Class<T> type, String name) {
//SPI should be get from SpiExtensionFactory
// 如果自动注入的值是接口且有 @SPI 注解,则直接返回
if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
return null;
}
// 先根据名称获取
for (ApplicationContext context : CONTEXTS) {
if (context.containsBean(name)) {
Object bean = context.getBean(name);
if (type.isInstance(bean)) {
return (T) bean;
}
}
}
...
// 再根据类型获取
for (ApplicationContext context : CONTEXTS) {
try {
return context.getBean(type);
} catch (NoUniqueBeanDefinitionException multiBeanExe) {
logger.warn("Find more than 1 spring extensions (beans) of type " + type.getName() + ", will stop auto injection. Please make sure you have specified the concrete parameter type and there's only one extension of that type.");
} catch (NoSuchBeanDefinitionException noBeanExe) {
if (logger.isDebugEnabled()) {
logger.debug("Error when get spring extension(bean) for type:" + type.getName(), noBeanExe);
}
}
}
...
}