计划阅读调试下Dubbo的源码,结合官方源码分析Dubbo,自身再分析总结
本文对应的Dubbo SPI
Dubbo SPI 使用
首先将配置文件放在META-INF/dubbo 目录下,与Java SPI不同的地方是,Dubbo SPI采用键值对方式,例如
1 | optimusPrime = org.apache.spi.OptimusPrime |
与Java SPI另一个不同点,Dubbo SPI需要在接口加上SPI注解
例如官网的例子,
1 | // 与Java SPI区别点 |
1 | public class DubboSPITest { |
Dubbo SPI源码分析
获取ExtensionLoader
对照上面的例子,ExtensionLoader<Robot> extensionLoader = ExtensionLoader.getExtensionLoader(Robot.class);
1 | "unchecked") ( |
上面的代码逻辑比较简单,就是去获取类对应的ExtensionLoader,如果缓存(EXTENSION_LOADERS
是ConcurrentMap<Class>, ExtensionLoader>>)中存在,则直接获取,不存在就新建一个,并存入缓存
获取扩展类
获取到ExtensionLoader之后,下一步获取实现类
1 | /** |
也是比较简单的逻辑,根绝name获取对应的实例,如果有直接返回,如果没有,就需要去新建
创建扩展类
1 | "unchecked") ( |
创建的逻辑复杂一下,主要逻辑为,1、获取扩展类,2、反射创建扩展类,3、扩展类本身依赖注入,4、对于扩展类的包装对象循环创建
加载扩展类
createExtension 方法的中,第一个就是根据name获取Class。
1 | private Map<String, Class<?>> getExtensionClasses() { |
目前为止,其过程比较简单,对SPI注解的值做校验,之后去不同目录加载所有的扩展类
1 | private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir) { |
前面的操作主要为,对配置文件解析,获取的name以及类名,通过反射加载类,之后进行缓存操作
1 | // 加载类之后,分为不同类型,对缓存的操作 |
至此,扩展类就已经加载完毕了。后续介绍Dubbo IOC部分