dubbo 内核包括 spi,aop,ioc,compiler
dubbo的spi存储在 dubbo里面jar文件的META-INF的dubbo目录的internal中存放dubbo的spi文件,dubbo模仿jdk的spi进行自己实现一些spi。可以在mysql的jar文件中进行查询到jdk的spi文件
1.详解jdk的spi例子
spi的设计目标是 因为我们是面向对象进行编程,在面向编程的过程中,模块与模块之间的都是通过接口进行关键,不包含实现类的编码,但是为了实现模块装配的过程中不写死代码,就需要一种服务发现机制。这种机制就是为了某个接口寻找实现类,有点类似于IOC的思想。
spi的约定:当一个提供服务者有多个服务实现时候,一般会在jar包的META-INF的service是目录下进行创建该接口的同名文件。该文件中包含该接口的实现类,当外部进行加载时候就可以通过该文件进行获取到接口以及实现类
既然spi有这么大的作用为啥dubbo 不适用jdk的spi 而要自己实现spi机制呢,小园子认为主要有两个原因:
1.jdk的spi机制是把所有的实现类都进行加载了 这样的话比较耗时耗力
2.jdk的spi机制是无法进行IOC和AOP的操作。
综合以上两点 dubbo的作者根据jdk的spi机制进行写了一个属于dubbo的spi机制下面说一下dubbo中spi的约定
1.dubbo的存储路径存储在META-INF/dubbo/internal问件下 文件的名字仍为类的全名称(包名+接口名)
2. 每个spi文件里面的内容都是 key=value 形式 根据key进行加载类
下面开始查看dubbo的源码
dubbo中spi的目的就是为了获取一个实现类的对象 途径:ExtensionLoader.getExtension(String name)来进行实现
实现路径
getExtensionLoader(Class<T> type) 就是为该接口 new 一个ExtensionLoader 然后缓存起来
getAdaptiveExtension() 获取一个扩展装饰类的对象 这个类有一个规则 如果它没有一个@Adaptive注解 就动态创建一个装饰类,例如Protocol$Adaptive对象
getExtension(String name) 获取一个对象
———————————————————-ExtensionLoader.getExtensionLoader(Class<T> type)
—————ExtensionLoader<Container> loader = ExtensionLoader.getExtensionLoader(Container.class);
———————-
ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
if (loader == null) {
EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));
loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
}
=========================================================================
private ExtensionLoader(Class<?> type) {
this.type = type;
objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
}
=================================
以上代码完成了ExtensionLoader两个属性的初始化
1.一个为type属性的值为Container.class 另一个objectFactory属性值 objectFactory是一个集合 里面包含spiExtensionFactory和springExtensionFactory
2.new 一个ExtensionLoader
关于这个objectFactory 我想说的是objectFactory的作用就是为了dubbo进行提供Ioc对象