Dubbo组件加载机制
Dubbo所有组件是通过SPI机制加载的,但Dubbo没有使用jdk提供的SPI,而是对SPI增强实现自己的Dubbo SPI。
SPI(Service Provider Interface)
SPI,Service Provider Interface,是一种服务发现机制。SPI本质是将接口的实现类的全限定名配置在文件中,由服务加载器读取配置文件,加载实现类。通过这种机制,可以为接口动态替换实现类。
Java SPI 示例
- 新增接口
package com.dawn.dubbo.spi;
/**
* Created by Dawn on 2019/10/16.
*/
public interface DawnSPI {
void getName();
}
- 实现类1
package com.dawn.dubbo.spi;
/**
* Created by Dawn on 2019/10/16.
*/
public class JavaSPI implements DawnSPI {
@Override
public void getName() {
System.out.println("Hi,JavaSPI");
}
}
- 实现类2
package com.dawn.dubbo.spi;
/**
* Created by Dawn on 2019/10/16.
*/
public class DubboSPI implements DawnSPI {
@Override
public void getName() {
System.out.println("Hi,DubboSPI");
}
}
- 在META-INF/services/目录下新增DawnSPI全限定名文件(org.dawn.dubbo.spi.DawnSPI),文件内容为接口实现类的所在包的全路径
补充下,为什么要在META-INF/services这个目录下新增全限定名文件,因为这个目录是ServiceLoader默认路径,打开ServiceLoader接口我们可以看到
- Java SPI测试类
/**
* Created by dawn on 2019/10/16.
*/
public class JavaSPITest {
@Test
public void getName(){
// 加载接口服务类
ServiceLoader<DawnSPI> serviceLoader = ServiceLoader.load(DawnSPI.class);
// :: jdk 1.8特性
serviceLoader.forEach(DawnSPI::getName);
// 等价
/* Iterator iterator = serviceLoader.iterator();
while (iterator.hasNext()){
DawnSPI dawnSPI= (DawnSPI) iterator.next();
dawnSPI.getName();
}*/
}
}
- 运行结果
Dubbo SPI示例
Dubbo SPI 实现逻辑封装在ExtensionLoader 类中,通过ExtensionLoader可以指定加载实现类,接口全限定名配置文件必须配置在META-INF/dubbo目录下,配置文件内容是key-value方式
同时与java spi不同,需要在接口添加dubbo 的SPI注解
- 接口添加dubbo SPI注解,实现同上
@SPI
public interface DawnSPI {
void getName();
}
- Dubo SPI 测试类
public class DubboSPITest {
@Test
public void getName(){
// 加载接口服务
ExtensionLoader<DawnSPI> extensionLoader=ExtensionLoader.getExtensionLoader(DawnSPI.class);
System.out.println("******************Dubbo Service Privice Interface");
// 指定加载实现类
DawnSPI dubboSPI=extensionLoader.getExtension("dubboSPI");
dubboSPI.getName();
// 指定加载实现类
DawnSPI javaSPI=extensionLoader.getExtension("javaSPI");
javaSPI.getName();
}
}
- 运行结果
总结
本文介绍了dubbo组件的加载机制 SPI,介绍了Java SPI 及Dubbo SPI使用示例。