dubboSPI和jdkSPI的区别

大标 2022年3月16日21:12:47
评论
15

dubboSPI和jdkSPI的区别

什么是SPI

SPI(Service Provider Interface)。Java在语言层面为我们提供了一种方便地创建可扩展应用的途径。SPI提供了一种JVM级别的服务发现机制,我们只需要按照SPI的要求,在jar包中进行适当的配置,jvm就会在运行时通过懒加载,帮我们找到所需的服务并加载。如果我们一直不使用某个服务,那么它不会被加载,一定程度上避免了资源的浪费。

JDK SPI最常见的例子就是java.sql.DriverManager中加载sql驱动的例子。

Java SPI

JDK自带的SPI的类是:java.util.ServiceLoader
使用方法以JDBC为例:

        // java.sql.DriverManager 首先在静态代码块中初始化全部懒加载进来
        // 首先拿到迭代器,而这个迭代器中,其实是拿一个扫描一个provider的 懒加载
        ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
        Iterator<Driver> driversIterator = loadedDrivers.iterator();
        // 以上代码还没有实例化过任何 Driver provider,以下代码,DriverManager才开始自动加载
        try {
            while (driversIterator.hasNext()) {
                driversIterator.next();
            }
        } catch (Throwable t) {
            // Do nothing
        }
        return null;

懒加载如下图所示,在load()了ServiceLoader后,经过参数检查 直接开始清空provider的缓存,然后重新获取provider。先查询已经缓存的provider有没有,如果没有再去遍历拿到新的provider。

而在加载过上述Driver provider之后,就会执行他的静态代码块,以DruidDriver为例具体代码如下所示:

    static {
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
            public Object run() {
                DruidDriver.registerDriver(DruidDriver.instance);
                return null;
            }
        });
    }

 public static boolean registerDriver(Driver driver) {
        try {
            DriverManager.registerDriver(driver);

            try {
                MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
                ObjectName objectName = new ObjectName(\"com.alibaba.druid:type=DruidDriver\");
                if (!mbeanServer.isRegistered(objectName)) {
                    mbeanServer.registerMBean(instance, objectName);
                }
            } catch (Throwable var3) {
                if (LOG == null) {
                    LOG = LogFactory.getLog(DruidDriver.class);
                }

                LOG.error(\"register druid-driver mbean error\", var3);
            }

            return true;
        } catch (Exception var4) {
            if (LOG == null) {
                LOG = LogFactory.getLog(DruidDriver.class);
            }

            LOG.error(\"registerDriver error\", var4);
            return false;
        }
    }

他相当于把 自己实例化后,又交给了DriverManager控制。
以上就是 jdk自带的SPI。

Dubbo SPI

对比和总结

  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
大标
  • 本文由 发表于 2022年3月16日21:12:47
  • 转载请务必保留本文链接:https://www.tanhuibiao.com/script/fuwuqi/5200.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: