RPC实现原理
RPC定义
RPC(Remote Procedure Call)远程过程调用,Remote Procedure Call Protocol是一个计算机通信协议。 它允许像调用本地方法一样调用远程服务。由于不在同一个内存空间,不能直接调用,需要通过网络来传达调用语义和传达调用的数据。
RPC调用过程
- 远程代理
- 序列化
- 网络传输
- 反序列化
Dubbo应用整体设计
- config 配置层,对外配置接口,以ServiceConfig和ReferenceConfig两个实现为中心,初始化配置信息
- proxy 服务代理层,Dubbo会为生产者和消费者生成代理类,用于远程调用,通过代理业务层对远程调用无感知
- registry 注册中心层,封装服务地址的注册与发现
- cluster 集群容错层,也叫路由层,封装调用失败容错机制,以及对多个provider节点的路由及负载均衡
- monitor 监控层,记录RPC调用次数和调用时间监控
- protocol 远程调用层,封装RPC调用过程,服务暴露和引用的功能入口
- exchange 信息交换层,封装请求响应模式,同步转异步
- transport 网络传输层,抽象mina和netty为统一接口,在其上封装一层接口方便扩展
- serialize 数据序列化层,负责传输数据的序列化和反序列化
Dubbo概述及使用
Dubbo总体分为业务层(Business)、RPC层、Remote层三大层。从程序员开发角度又分为API层和SPI层,其中Service和Config属于API层,其它都属于SPI层。
Dubbo的SPI机制
Dubbo的SPI机制是对Java SPI 机制的升级与拓展,它在Java SPI基础上扩展了 IoC 和 AOP。
SPI(Service Provider Interface),是java提供的一套用来被第三方实现或者扩展的接口,可以用来启用框架扩展和替换组件。SPI的作用就是为这些被扩展的API寻找服务实现。
API(Application Programming Interface)实现方制定的接口实现,供开发人员调用。简单来说就是实现方开发出来哪些接口,调用者就只有选择权,没有拓展权。
SPI(Service Provider Interface),由调用方指定接口规范,提供给外部实现,调用方在调用时选择自己需要的外部实现。一般被框架拓展人员使用。
Java SPI 规定jar包读取的路径必须为 META-INF/services(文件接口名完整包路径)
/**
* 不能按需加载
* 不够灵活,不能动态的AOP和IOC
* dubbo SPI
*/
public class JdkSpiMain {
public static void main(String[] args) {
ServiceLoader<JdkSpiServiceInterface> serviceLoader = ServiceLoader.load(JdkSpiServiceInterface.class);
Iterator<JdkSpiServiceInterface> iterator = serviceLoader.iterator();
while (iterator.hasNext()) {
JdkSpiServiceInterface spiInterface = iterator.next();
spiInterface.getColor();
}
}
}
Dubbo源码
定义@SPI注解,标识接口为可拓展的。
package org.apache.dubbo.common.extension;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface SPI {
String value() default "";
}
定义@Adaptive注解,保证dubbo内部调用具体实现时适配机制,而不是硬编码实现。
package org.apache.dubbo.common.extension;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Adaptive {
String[] value() default {};
}
Dubbo SPI机制拓展支持AOP 和 IOC
@SPI
public interface Car {
public void getColor();
@Adaptive("car")
public void getColorForUrl(URL url);
}
创建一个包装类,通过构造函数注入Car实例,对包装类进行切面
public class CarWrapper implements Car {
private Car car;
//构造方法注入实例
public CarWrapper(Car car){
System.out.println("init car wrapper");
this.car=car;
}
//重写getColor方法对其进行切面操作
@Override
public void getColor() {
System.out.println("==========before aop===========");
car.getColor();
System.out.println("==========after aop===========");
}
}
@Adaptive 实现接口自适应机制。 优先级 类>接口>方法。
new ExtensionLoader<T>(Class<?> type)
private ExtensionLoader(Class<?> type) {
this.type = type;
objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
}
扩展工厂扩展接口,扩展类都要实现
@SPI
public interface ExtensionFactory {
/**
* Get extension.
*
* @param type object type.
* @param name object name.
* @return object instance.
*/
<T> T getExtension(Class<T> type, String name);
}
Dubbo默认使用 SPI扩展工厂
public class SpiExtensionFactory implements ExtensionFactory {
@Override
public <T> T getExtension(Class<T> type, String name) {
if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);
if (!loader.getSupportedExtensions().isEmpty()) {
//调用了自适应扩展
return loader.getAdaptiveExtension();
}
}
return null;
}
}
自适应扩展工厂,匹配dubbo spi扩展机制
@Adaptive
public class AdaptiveExtensionFactory implements ExtensionFactory {
//扩展对象的集合,默认的可以分为dubbo 的SPI中接口实现类对象或者Spring bean对象
private final List<ExtensionFactory> factories;
//构造函数 加载自适应实例对象
public AdaptiveExtensionFactory() {
ExtensionLoader<ExtensionFactory> loader = ExtensionLoader.getExtensionLoader(ExtensionFactory.class);
List<ExtensionFactory> list = new ArrayList<ExtensionFactory>();
//遍历所有支持的扩展名
for (String name : loader.getSupportedExtensions()) {
//扩展对象加入到集合中
list.add(loader.getExtension(name));
}
//返回一个不可修改的集合
factories = Collections.unmodifiableList(list);
}
@Override
public <T> T getExtension(Class<T> type, String name) {
for (ExtensionFactory factory : factories) {
//通过扩展接口和扩展名获得扩展对象
T extension = factory.getExtension(type, name);
if (extension != null) {
return extension;
}
}
return null;
}
}
Spring扩展工厂
public class SpringExtensionFactory implements ExtensionFactory {
private static final Logger logger = LoggerFactory.getLogger(SpringExtensionFactory.class);
private static final Set<ApplicationContext> CONTEXTS = new ConcurrentHashSet<ApplicationContext>();
public static void addApplicationContext(ApplicationContext context) {
CONTEXTS.add(context);
if (context instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext) context).registerShutdownHook();
}
}
public static void removeApplicationContext(ApplicationContext context) {
CONTEXTS.remove(context);
}
public static Set<ApplicationContext> getContexts() {
return CONTEXTS;
}
// currently for test purpose
public static void clearContexts() {
CONTEXTS.clear();
}
@Override
@SuppressWarnings("unchecked")
public <T> T getExtension(Class<T> type, String name) {
//判断如果是接口 并且加了@SPI注解 返回null。是spi应该调SpiExtensionFactory
if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
return null;
}
//判断spring容器中是否存在这样一个bean 有就返回没有就返回null
for (ApplicationContext context : CONTEXTS) {
T bean = BeanFactoryUtils.getOptionalBean(context, name, type);
if (bean != null) {
return bean;
}
}
//logger.warn("No spring extension (bean) named:" + name + ", try to find an extension (bean) of type " + type.getName());
return null;
}
}
Dubbo SPI 工作原理
案例
public static void main(String[] args) {
ExtensionLoader<Car> extensionLoader = ExtensionLoader.getExtensionLoader(Car.class);
Car redCar = extensionLoader.getExtension("red");
redCar.getColor();
Car greeCar = extensionLoader.getExtension("gree");
Map<String, String> map = new HashMap<>();
map.put("car","black");
URL url = new URL("","",1,map);
greeCar.getColorForUrl(url);
greeCar.getColor();
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
ExtensionLoader 加载器
先获取Car类型的加载器
ExtensionLoader<Car> extensionLoader = ExtensionLoader.getExtensionLoader(Car.class);
在Dubbo中每一个SPI扩展接口都有自己的ExtensionLoader 扩展类加载器
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
if (type == null) {
throw new IllegalArgumentException("Extension type == null");
}
// 必须是接口
if (!type.isInterface()) {
throw new IllegalArgumentException("Extension type (" + type + ") is not an interface!");
}
//必须有@SPI注解
if (!withExtensionAnnotation(type)) {
throw new IllegalArgumentException("Extension type (" + type +
") is not an extension, because it is NOT annotated with @" + SPI.class.getSimpleName() + "!");
}
//从EXTENSION_LOADERS(ConcurrentMap<Class<?>,ExtensionLoader<?>>)缓存中查询是否映存在对应的ExtensionLoader
ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
if (loader == null) {
//不存在就new一个并放缓存里
EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));
loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
}
//返回接口锁对应的ExtensionLoader实例
return loader;
}
从META-INF/service/ 中读取com.marx.dubbo_spi.api.Car配置文件
red = com.nx.samuel.dubbo_spi.impl.RedCar
根据key读取配置加载实例
Car redCar = extensionLoader.getExtension("red");
加载实例代码逻辑
public T getExtension(String name) {
return getExtension(name, true);
}
/**
* 扩展实例缓存
* key = 扩展点名称
* value = 扩展实例的包装好的Holder实例(实例里有这个扩展点实例的实际对象)
* @param name
* @param wrap
* @return
*/
public T getExtension(String name, boolean wrap) {
if (StringUtils.isEmpty(name)) {
throw new IllegalArgumentException("Extension name == null");
}
//扩展点名称是true 那么返回默认的扩展类
if ("true".equals(name)) {
return getDefaultExtension();
}
//扩展实例缓存容器,从缓存中获取,没有就创建一个放入缓存中
final Holder<Object> holder = getOrCreateHolder(name);
......
}
getOrCreateHolder(name) 根据扩展名,从cachedInstances(ConcurrentMap<String, Holder<Object>>)中获取扩展实例对象,获取到了则直接返回
/**
* 获取活创建一个Holder对象
* @param name
* @return
*/
private Holder<Object> getOrCreateHolder(String name) {
//通过扩展名从扩展实例缓存中获取holder对象
Holder<Object> holder = cachedInstances.get(name);
if (holder == null) {
cachedInstances.putIfAbsent(name, new Holder<>());
holder = cachedInstances.get(name);
}
return holder;
}
调用getOrCreateHolder 如果没有获取到 则继续执行代码
public T getExtension(String name, boolean wrap) {
if (StringUtils.isEmpty(name)) {
throw new IllegalArgumentException("Extension name == null");
}
//扩展点名称是true 那么返回默认的扩展类
if ("true".equals(name)) {
return getDefaultExtension();
}
//扩展实例缓存容器,从缓存中获取,没有就创建一个放入缓存中
final Holder<Object> holder = getOrCreateHolder(name);
Object instance = holder.get();
//DCL
if (instance == null) {
synchronized (holder) {
instance = holder.get();
if (instance == null) {
//创建扩展点实例
instance = createExtension(name, wrap);
//放入缓存
holder.set(instance);
}
}
}
return (T) instance;
}
如果instance == null 即 还是没有获取到扩展点实例对象,则调用 createExtension 创建实例,并放入缓存中
/**
* 根据扩展名加载扩展类对应的class对象
* @param name
* @param wrap
* @return
*/
@SuppressWarnings("unchecked")
private T createExtension(String name, boolean wrap) {
//从缓存中获取扩展类对象
Class<?> clazz = getExtensionClasses().get(name);
//没有获取到就抛出异常
if (clazz == null) {
throw findException(name);
}
// 获取到了类对象继续执行
try {
//根据clazz对象,从扩展点实例缓存中获取对应的实例对象
T instance = (T) EXTENSION_INSTANCES.get(clazz);
if (instance == null) {
//如果通过扩展类对象还是没有获取到扩展实例 则通过扩展类创建一个实例放入缓存中
EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
instance = (T) EXTENSION_INSTANCES.get(clazz);
}
//实现依赖注入,通过setter方法自动注入对应的属性实例
injectExtension(instance);
//自动注入缓存中的所有包装类
if (wrap) {
List<Class<?>> wrapperClassesList = new ArrayList<>();
if (cachedWrapperClasses != null) {
wrapperClassesList.addAll(cachedWrapperClasses);
wrapperClassesList.sort(WrapperComparator.COMPARATOR);
Collections.reverse(wrapperClassesList);
}
if (CollectionUtils.isNotEmpty(wrapperClassesList)) {
for (Class<?> wrapperClass : wrapperClassesList) {
Wrapper wrapper = wrapperClass.getAnnotation(Wrapper.class);
if (wrapper == null
|| (ArrayUtils.contains(wrapper.matches(), name) && !ArrayUtils.contains(wrapper.mismatches(), name))) {
instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
}
}
}
}
//初始化实例并返回
initExtension(instance);
return instance;
} catch (Throwable t) {
throw new IllegalStateException("Extension instance (name: " + name + ", class: " +
type + ") couldn't be instantiated: " + t.getMessage(), t);
}
}
getExtensionClasses 获取所有的扩展类 cachedClasses (Holder<Map<String, Class<?>>>)
/**
* 加载扩展点对应的类
* 从缓存中获取所有的扩展点的类,如果没有就重新扫描一次,并缓存起来
* key:扩展名
* value:对应的class对象
* @return
*/
private Map<String, Class<?>> getExtensionClasses() {
//1、从缓存中获取出已经缓存的扩展点的classs
Map<String, Class<?>> classes = cachedClasses.get();
if (classes == null) {
//如果没有缓存过,那么就根据配置扫描
synchronized (cachedClasses) {
classes = cachedClasses.get();
if (classes == null) {
//扫描配置文件,加载配置的扩展点的class
classes = loadExtensionClasses();
//将稻苗到的class存入到缓存
cachedClasses.set(classes);
}
}
}
return classes;
}
loadExtensionClasses 扫描配置 加载配置扩展实现类,Map<String,Class<?>> extensionClasses ,key对应配置文件的扩展名,value对应配置文件的类全名
private Map<String, Class<?>> loadExtensionClasses() {
/**
* 获取注解了SPI的接口中指定的默认的实现类的名称
* 存入到内存缓存中
* 接口没有标注@SPI或者标注了@SPI注解但是没有指定默认实现类的名称时不做任务的处理
*/
cacheDefaultExtensionName();
Map<String, Class<?>> extensionClasses = new HashMap<>();
// 遍历加载策略
for (LoadingStrategy strategy : strategies) {
loadDirectory(extensionClasses, strategy.directory(), type.getName(), strategy.preferExtensionClassLoader(), strategy.overridden(), strategy.excludedPackages());
loadDirectory(extensionClasses, strategy.directory(), type.getName().replace("org.apache", "com.alibaba"), strategy.preferExtensionClassLoader(), strategy.overridden(), strategy.excludedPackages());
}
return extensionClasses;
}
加载策略 LoadingStrategy [ ] strategies
private static LoadingStrategy[] loadLoadingStrategies() {
return stream(load(LoadingStrategy.class).spliterator(), false)
.sorted()
.toArray(LoadingStrategy[]::new);
}
load方法 调用类加载器加载了 LoadingStrategy.class,LoadingStrategy 有4种实现
-
Dubbo 外部加载策略 DubboExternalLoadingStrategy,优先级 MAX_PRIORITY + 1,加载目录 META-INF/dubbo/external/
-
Dubbo 内部加载策略,DubboInternalLoadingStrategy, 优先级 MAX_PRIORITY (Integer最小值), 加载目录 META-INF/dubbo/internal/
-
Dubbo 一般加载策略,DubboLoadingStrategy,优先级 NORMAL_PRIORITY (0),加载目录 META-INF/dubbo/
-
SPI默认加载策略,ServicesLoadingStrategy,优先级 MIN_PRIORITY (Integer最大值),加载目录 META-INF/dubbo/services/
循环调用 loadDirectory 加载目录,获取到配置文件 URL
private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir, String type,
boolean extensionLoaderClassLoaderFirst, boolean overridden, String... excludedPackages) {
//配置文件的全路径:默认路径前缀+接口的全限定名
String fileName = dir + type;
try {
Enumeration<java.net.URL> urls = null;
// 获取当前线程的类加载器
ClassLoader classLoader = findClassLoader();
// try to load from ExtensionLoader's ClassLoader first
if (extensionLoaderClassLoaderFirst) {
//获取加载ExtenstionLoader.calss这个类的类加载器
ClassLoader extensionLoaderClassLoader = ExtensionLoader.class.getClassLoader();
if (ClassLoader.getSystemClassLoader() != extensionLoaderClassLoader) {
//如果两个类加载器不同,就默认使用extensionLoaderClassLoader
urls = extensionLoaderClassLoader.getResources(fileName);
}
}
if (urls == null || !urls.hasMoreElements()) {
if (classLoader != null) {
urls = classLoader.getResources(fileName);
} else {
urls = ClassLoader.getSystemResources(fileName);
}
}
if (urls != null) {
//解析并加载配置文件中配置的实现类到extensionClasses缓存中
while (urls.hasMoreElements()) {
java.net.URL resourceURL = urls.nextElement();
loadResource(extensionClasses, classLoader, resourceURL, overridden, excludedPackages);
}
}
} catch (Throwable t) {
logger.error("Exception occurred when loading extension class (interface: " +
type + ", description file: " + fileName + ").", t);
}
}
根据 URL解析配置文件,使用Class.forName加载类,并调用 loadClass
private void loadResource(Map<String, Class<?>> extensionClasses, ClassLoader classLoader,
java.net.URL resourceURL, boolean overridden, String... excludedPackages) {
try {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(resourceURL.openStream(), StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
final int ci = line.indexOf('#');
if (ci >= 0) {
line = line.substring(0, ci);
}
line = line.trim();
if (line.length() > 0) {
try {
String name = null;
int i = line.indexOf('=');
if (i > 0) {
//配置的接口的实现的名字
name = line.substring(0, i).trim();
//配置的接口的实现的名字
line = line.substring(i + 1).trim();
}
if (line.length() > 0 && !isExcluded(line, excludedPackages)) {
/**
* 加载配置的class到extensionClasses,使用Class.forName方式加载class
* loadClass方法加载口哦站点的实现的class,这个方法的主要作用是对解析的class进行分类缓存
*/
loadClass(extensionClasses, resourceURL, Class.forName(line, true, classLoader), name, overridden);
}
} catch (Throwable t) {
IllegalStateException e = new IllegalStateException("Failed to load extension class (interface: " + type + ", class line: " + line + ") in " + resourceURL + ", cause: " + t.getMessage(), t);
exceptions.put(line, e);
}
}
}
}
} catch (Throwable t) {
logger.error("Exception occurred when loading extension class (interface: " +
type + ", class file: " + resourceURL + ") in " + resourceURL, t);
}
}
调用loadClass进行分类缓存, 如果是Wrapper 包装类缓存到cacheWrapperClass,如果是配置@Adaptive 缓存到cacheAdaptiveClass中,如果都不是则判断是不是加了@Activate注解,缓存extensionClasses
private void loadClass(Map<String, Class<?>> extensionClasses, java.net.URL resourceURL, Class<?> clazz, String name,
boolean overridden) throws NoSuchMethodException {
//判断实现类是否显现了type接口
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.");
}
//1、如果配置了@Adaptive注解,表示这是一个自适应类,缓存到cacheAdaptiveClass中
if (clazz.isAnnotationPresent(Adaptive.class)) {
cacheAdaptiveClass(clazz, overridden);
} else if (isWrapperClass(clazz)) {
//2、如果是一个wapper类就缓存到cacheWrapperClass中
cacheWrapperClass(clazz);
} else {
//这里相当于校验类中是否存在默认的构造函数 如果不存在就抛出异常了
clazz.getConstructor();
if (StringUtils.isEmpty(name)) {//配置文件没有指定XX=com.。。。。中的XX这种已经启用了,不看了
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)) {
//3、如果扩展点配置的实现类使用的@Activate注解,就讲对应的注解信息缓存
cacheActivateClass(clazz, names[0]);
for (String n : names) {
cacheName(clazz, n);// 缓存扩展点实现类的class和扩展点名称的对应关系
saveInExtensionClass(extensionClasses, clazz, n, overridden);//将class存入到extensionClasses中
}
}
}
}
injectExtension 实现依赖项注入。获取所有类的setter方法。 1.如果setter方法不是私有的和基础数据类型 并且没有@DisableInject注解来注解这个setter方法,就自动给相关属性注入默认的实现类 2.如果setter方法属性是一个接口,并且这个接口有多个实现类,则会增加@Adaptive注解 自适应加载配置的默认实现
/**
* 这里实现了IOC和AOP
* 获取类的所有的setter方法
* @param instance
* @return
*/
private T injectExtension(T instance) {
/**
* objectFactory为空的话就不属性注入了
* objectFactory 是ExtensionFactory实例:从Dubbo容器和Spring容器中获取setter属性的默认扩展实例
*/
if (objectFactory == null) {
return instance;
}
try {
for (Method method : instance.getClass().getMethods()) {
//不是setter就不管了,条件1、public 2、set开头 3、只有一个参数
if (!isSetter(method)) {
continue;
}
/**
* Check {@link DisableInject} to see if we need auto injection for this property
*/
//setter方法加了DisableInject注解就不管了
if (method.getAnnotation(DisableInject.class) != null) {
continue;
}
Class<?> pt = method.getParameterTypes()[0];
//级别数据类型也不管了
if (ReflectUtils.isPrimitives(pt)) {
continue;
}
try {
//获取setter方法的属性值
String property = getSetterProperty(method);
Object object = objectFactory.getExtension(pt, property);
if (object != null) {
//获取到属性的实例后,调用setter方法为该成员赋值
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;
}
objectFactory 是 ExtensionLoader 中的实例变量,下面是ExtensionLoader的有参构造函数。 判断了如果参数类型不是 ExtensionFactory,则调用 getExtensionLoader 加载 ExtensionFactory 调用了自适应实例。
private ExtensionLoader(Class<?> type) {
this.type = type;
objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
}
初始化实例,初始化声明周期
private void initExtension(T instance) {
if (instance instanceof Lifecycle) {
Lifecycle lifecycle = (Lifecycle) instance;
lifecycle.initialize();
}
}
将配置中心ConfigCenter的信息存入到本地缓存中
public void initialize() throws IllegalStateException {
ConfigManager configManager = ApplicationModel.getConfigManager();
Optional<Collection<ConfigCenterConfig>> defaultConfigs = configManager.getDefaultConfigCenter();
defaultConfigs.ifPresent(configs -> {
for (ConfigCenterConfig config : configs) {
this.setExternalConfigMap(config.getExternalConfiguration());
this.setAppExternalConfigMap(config.getAppExternalConfiguration());
}
});
this.externalConfiguration.setProperties(externalConfigurationMap);
this.appExternalConfiguration.setProperties(appExternalConfigurationMap);
}
ExtensionLoader.getExtension(String name) 完整流程图
xml解析暴露 dubbo:service过程
Dubbo项目中 dubbo-config模块下的config-spring中有一个dubbo.xsd配置文件。
在这个配置文件中配置了dubbo的文件约束。
xml解析配置文件 spring.handlers中配置了Dubbo解析xml的处理器
http://dubbo.apache.org/schema/dubbo=org.apache.dubbo.config.spring.schema.DubboNamespaceHandler
http://code.alibabatech.com/schema/dubbo=org.apache.dubbo.config.spring.schema.DubboNamespaceHandler
DubboNamespaceHandler 处理器重写了父类的两个方法init和parse。parse主要做解析配置操作,init完成了初始化Beandefinision
public class DubboNamespaceHandler extends NamespaceHandlerSupport implements ConfigurableSourceBeanMetadataElement {
static {
Version.checkDuplicate(DubboNamespaceHandler.class);
}
@Override
public void init() {
registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
registerBeanDefinitionParser("config-center", new DubboBeanDefinitionParser(ConfigCenterBean.class, true));
registerBeanDefinitionParser("metadata-report", new DubboBeanDefinitionParser(MetadataReportConfig.class, true));
registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
registerBeanDefinitionParser("metrics", new DubboBeanDefinitionParser(MetricsConfig.class, true));
registerBeanDefinitionParser("ssl", new DubboBeanDefinitionParser(SslConfig.class, true));
registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
registerBeanDefinitionParser("annotation", new AnnotationBeanDefinitionParser());
}
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
BeanDefinitionRegistry registry = parserContext.getRegistry();
//注册注解驱动处理器
registerAnnotationConfigProcessors(registry);
//注册为普通的bean
registerCommonBeans(registry);
//parse 解析标签
BeanDefinition beanDefinition = super.parse(element, parserContext);
setSource(beanDefinition);
return beanDefinition;
}
//注册注解驱动处理器
private void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
AnnotationConfigUtils.registerAnnotationConfigProcessors(registry);
}
}
DubboBeanUtils.registerCommonBeans
static void registerCommonBeans(BeanDefinitionRegistry registry) {
// 注册加了@Reference注解的bean, ReferenceAnnotationBeanPostProcessor
registerInfrastructureBean(registry, ReferenceAnnotationBeanPostProcessor.BEAN_NAME,
ReferenceAnnotationBeanPostProcessor.class);
//注册别名配置处理处理器 DubboConfigAliasPostProcessor
registerInfrastructureBean(registry, DubboConfigAliasPostProcessor.BEAN_NAME,
DubboConfigAliasPostProcessor.class);
//重点看这个方法,注册基础Bean,Dubbo应用的注册事件监听器
registerInfrastructureBean(registry, DubboApplicationListenerRegistrar.BEAN_NAME,
DubboApplicationListenerRegistrar.class);
// Dubbo配置文件属性处理器 PropertyValueBeanPostProcessor
registerInfrastructureBean(registry, DubboConfigDefaultPropertyValueBeanPostProcessor.BEAN_NAME,
DubboConfigDefaultPropertyValueBeanPostProcessor.class);
// Dubbo 配置服务提前暴露 EarlyInitializationPostProcessor
registerInfrastructureBean(registry, DubboConfigEarlyInitializationPostProcessor.BEAN_NAME,
DubboConfigEarlyInitializationPostProcessor.class);
}
DubboApplicationListenerRegistrar.class 实现了ApplicationContextAware接口,将会在Spring容器初始化之后调用setApplicationContext方法,可以获取到Spring容器的上下文进行操作
public class DubboApplicationListenerRegistrar implements ApplicationContextAware {
public static final String BEAN_NAME = "dubboApplicationListenerRegister";
/**
* 实现了ApplicationContextAware接口的类会被调用setApplicationContext方法,从而获取到spring容器的上下文
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (!isAssignable(ConfigurableApplicationContext.class, applicationContext.getClass())) {
throw new IllegalArgumentException("The argument of ApplicationContext must be ConfigurableApplicationContext");
}
//添加应用监听器
addApplicationListeners((ConfigurableApplicationContext) applicationContext);
}
private void addApplicationListeners(ConfigurableApplicationContext context) {
//添加监听context.refresh事件的监听器,主要是为了服务注册和服务暴露
context.addApplicationListener(createDubboBootstrapApplicationListener(context));
//添加Dubbo生命周期的监听器
context.addApplicationListener(createDubboLifecycleComponentApplicationListener(context));
}
private ApplicationListener<?> createDubboBootstrapApplicationListener(ConfigurableApplicationContext context) {
return new DubboBootstrapApplicationListener(context);
}
private ApplicationListener<?> createDubboLifecycleComponentApplicationListener(ConfigurableApplicationContext context) {
return new DubboLifecycleComponentApplicationListener(context);
}
}
在Spring中添加了监听器DubboBootstrapApplicationListener
public class DubboBootstrapApplicationListener extends OnceApplicationContextEventListener implements Ordered {
public static final String BEAN_NAME = "dubboBootstrapApplicationListener";
private final DubboBootstrap dubboBootstrap;
//监听器构造方法中实例化DubboBootstrap实例
public DubboBootstrapApplicationListener(ApplicationContext applicationContext) {
super(applicationContext);
this.dubboBootstrap = DubboBootstrap.getInstance();
}
@Override
public void onApplicationContextEvent(ApplicationContextEvent event) {
if (event instanceof ContextRefreshedEvent) {
//如果是spring容器刷新事件,就启动dubbo服务
onContextRefreshedEvent((ContextRefreshedEvent) event);
} else if (event instanceof ContextClosedEvent) {
//如果是spring容器关闭事件,就停止dubbo服务
onContextClosedEvent((ContextClosedEvent) event);
}
}
private void onContextRefreshedEvent(ContextRefreshedEvent event) {
dubboBootstrap.start();
}
private void onContextClosedEvent(ContextClosedEvent event) {
dubboBootstrap.stop();
}
@Override
public int getOrder() {
return LOWEST_PRECEDENCE;
}
}
Dubbo启动,核心就做2件事。 1.初始化 2.暴露服务
public DubboBootstrap start() {
//1. 判断是不是没有启动,如果是就将true设置给started表示,然后执行启动程序
if (started.compareAndSet(false, true)) {
ready.set(false);
//2. 初始化
initialize();
if (logger.isInfoEnabled()) {
logger.info(NAME + " is starting...");
}
// 3. export Dubbo Services 暴露Provider的 Services
exportServices();
// Not only provider register
if (!isOnlyRegisterProvider() || hasExportedServices()) {
// 4.导出元数据 export MetadataService
exportMetadataService();
//5. Register the local ServiceInstance if required通过spi方式获取服务注册中心
registerServiceInstance();
}
//6 处理Consumer的ReferenceConfig
referServices();
if (asyncExportingFutures.size() > 0) {//异步操作,在exportServices中添加
new Thread(() -> {
try {
this.awaitFinish();
} catch (Exception e) {
logger.warn(NAME + " exportAsync occurred an exception.");
}
ready.set(true);
if (logger.isInfoEnabled()) {
logger.info(NAME + " is ready.");
}
}).start();
} else {
ready.set(true);
if (logger.isInfoEnabled()) {
logger.info(NAME + " is ready.");
}
}
if (logger.isInfoEnabled()) {
logger.info(NAME + " has started.");
}
}
return this;
}
未完待续...