JAVA 原生SPI和Dubbo SPI简单使用对比

简介

SPI是JDK内置的一种服务提供发现机制,可以用来启用框架扩展和替换组件,主要是被框架的开发人员使用,比如java.sql.Driver接口,其他不同厂商可以针对同一接口做出不同的实现,MySQL和PostgreSQL都有不同的实现提供给用户,而Java的SPI机制可以为某个接口寻找服务实现。Java中SPI机制主要思想是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要,其核心思想就是解耦。

JDK SPI如何使用

    1. 定义一个接口
package com.test.spi;
public interface Driver {
	void getDriver();
}
  • 2.实现接口
package com.test.spi.impl;
import  com.test.spi.Driver;
public class MysqlDriver implements Driver {
	public void getDriver(){
		System.out.println("Im mysql");
	}
}

package com.test.spi.impl;
import  com.test.spi.Driver;
public class PostgreDriver implements Driver {
	public void getDriver(){
		System.out.println("Im postgre");
	}
}
    1. 在META-INF/services/目录里创建一个以 com.test.spi.Driver的文件,这个文件里的内容就是这个接口的具体的实现类。
com.test.spi.impl.MysqlDriver 
com.test.spi.impl.PostgreDriver 
    1. 使用 ServiceLoader 来加载配置文件中指定的实现
package com.test.spi;
import java.util.ServiceLoader;
import com.test.spi.Driver;
public class SPIDemo {
    public static void main(String[] args) {
        ServiceLoader<Driver> serviceLoader = ServiceLoader.load(Driver.class);
        // 执行不同厂商的业务实现,具体根据业务需求配置
        for (Driver driver: serviceLoader) {
            driver.getDriver();
        }
    }
}

输出如下:

Im mysql
Im postgre

Dubbo SPI如何使用

---定义基础应用类

public interface Fruit {}
public class Apple implements Fruit {}
public class Banana implements Fruit{}



----定义SPI类

@SPI("banana")
public interface PlantsWater {

    Fruit grant();

    @Adaptive
    String watering(URL url);
}


public class AppleWater implements PlantsWater {
    public Fruit grant() {
        return new Apple();
    }

    public String watering(URL url) {
        System.out.println("watering apple");
        return "watering finished";
    }
}


public class BananaWater implements PlantsWater {

    public Fruit grant() {
        return new Banana();
    }

    public String watering(URL url) {
        System.out.println("watering banana");
        return "watering success";
    }
}



----resources文件 org.apache.dubbo.spi.example.PlantsWater

apple=org.apache.dubbo.spi.example.AppleWater
banana=org.apache.dubbo.spi.example.BananaWater


------测试代码内容

public class ExtensionLoaderDemo {

    public static void main(String[] args) {
        // 首先创建一个模拟用的URL对象
        URL url = URL.valueOf("dubbo://192.168.0.101:20880?plants.water=apple");
        // 通过ExtensionLoader获取一个PlantsWater对象,getAdaptiveExtension已经加载了所有SPI类
        PlantsWater plantsWater = ExtensionLoader.getExtensionLoader(PlantsWater.class)
                .getAdaptiveExtension();
        // 使用该PlantsWater调用其"自适应标注的"方法,获取调用结果
        String result = plantsWater.watering(url);
        System.out.println(result);
    }
}


-----实际输出内容

十月 11, 2019 7:48:51 下午 org.apache.dubbo.common.logger.LoggerFactory info
信息: using logger: org.apache.dubbo.common.logger.jcl.JclLoggerAdapter
watering apple
watering finished

Process finished with exit code 0

JDK 和 Dubbo SPI简单对比

  • JDK 标准的 SPI 会一次性实例化扩展点所有实现,如果有扩展实现初始化很耗时,但如果没用上也加载,会很浪费资源
  • JDK SPI 如果扩展点加载失败,就失败了,给用户没有任何通知
  • 增加了对扩展点 IoC 和 AOP 的支持,一个扩展点可以直接 setter 注入其它扩展点
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值