Dubbo拓展点加载机制

Java SPI(Service Provider Interface)

(1)接口

public interface SPIService {
    public void printService();
}

(2)接口实现1

public class SPIServiceImpl implements SPIService {
    public void printService() {
        System.out.println("Hello World");
    }
}

(3)接口实现2

public class SPIServiceImpl2  implements SPIService {
    public void printService() {
        System.out.println("Hello World2");
    }
}

(4)接口实现2

public class SPIServiceImpl3 implements SPIService {
    public void printService() {
        System.out.println("Hello World3");
    }
}

(5)在resource目录下建立META-INF/services目录,建立接口的全路径名文件(这里是gdut.ff.spi.SPIService),在文件里以分行符分隔接口实现类的全路径名。
image.png

(6)Main方法

import java.util.ServiceLoader;
 
public class SPIServiceMain {
    public static void main(String[] args) {
        ServiceLoader<SPIService> serviceLoader = ServiceLoader.load(SPIService.class);
        for (SPIService spiService:serviceLoader) {
            spiService.printService();
        }
    }
}

java.util.ServiceLoader可以获取接口的全部实现,具体调用哪个实现是用户在META-INF/services中配置。

Dubbo SPI

(1)在接口上添加注解@SPI

import org.apache.dubbo.common.extension.SPI;

@SPI("spiServiceImpl")
public interface SPIService {
    public void printService();
}

(2)在META-INF/dubbo/internal文件夹下建立全路径名配置文件,内容如下

spiServiceImpl=gdut.ff.spi.SPIServiceImpl

(3)Main方法:通过ExtensionLoader获取接口SPIService.class的默认实现

public class SPIServiceMain {
    public static void main(String[] args) {
        SPIService defaultExtension = ExtensionLoader.getExtensionLoader(SPIService.class).getDefaultExtension();
        defaultExtension.printService();
    }
}

Java SPI 和 Dubbo SPI 对比

(1) Java SPI会一次性实例化所有拓展点的实现,而Dubbo SPI并不会立即全部初始化。
(2) Dubbo SPI实现了IoC和AOP机制。
(3) Dubbo SPI兼容Java SPI的配置方式和配置内容,在Dubbo启动的时候,会扫描META-INF/services/,META-INF/dubbo/,META-INF/dubbo/internal/三个目录

拓展点注解 @SPI

(1)@SPI可以使用在类、接口和枚举类上。
(2)标志这是Dubbo SPI接口。
(3)SPI注解有一个value属性,可以通过这个属性设置这个接口的默认实现类。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface SPI {
    /**
     * 默认实现类名称
     */
    String value() default "";
}

拓展点自适应注解 @Adaptive

(1)@Adaptive注解可以标记在类、接口、枚举和方法上。
(2)使用@Adaptive注解,可以动态地通过URL中的参数来确定具体使用的实现类,从而解决了自动加载中的实例注入问题。
(3)当传递的参数URL没有参数key可以匹配@Adaptive的value数组的某一个值,就会使用@SPI("XXX")默认实现。
(4)当传递的参数URL有参数key可以匹配@Adaptive的value数组的某一个值(顺序是key依次匹配),就使用该key对应的value值。查找该value值在配置文件(META-INF/dubbo/internal/目录下)对应的实现类。
(5)当在某个实现类上加了@Adaptive注解,优先级最高,无论默认实现@SPI的值是什么和URL传递了什么参数,都会直接调用带有@Adaptive注解的类。
(6)方法级别注解会生成和编译动态实现类,而类级别的注解不会生成动态类。
(7)会缓存两个与@Adaptive有关的对象,Adaptive具体实现类的Class类型缓存在cachedAdaptiveClass中;Class的具体实例化对象缓存在cachedAdaptiveInstance中。

@SPI("spiServiceImpl")
public interface SPIService {
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值