栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

Dubbo学习记录(三)----JDK之SPI机制

Dubbo学习记录(三)----JDK之SPI机制

JDK之SPI机制

个人理解

    SPI就是一种约定机制,通常情况下, 我们服务都会有一个接口和一个实现类,当服务提供者提供某个服务时,需要在/meta-INF/services/目录下创建以接口路径命名的文在这个文件中, 指定我们实现的服务com.demo.impl.UserServiceImpl;
package com.tuling;
public interface Product {
    void use();
}
public class Phone implements Product{
    @Override
    public void use() {
        System.out.println("call");
    }
}
package com.tuling;

public class Food implements Product{
    @Override
    public void use() {
        System.out.println("eat");
    }
}

在/meta-INF/services/创建一个com.demo.UserService文件

com.tuling.Phone
com.tuling.Food

JDK 的SPI调用机制

 ServiceLoader productServiceLoader = ServiceLoader.load(Product.class);
 Iterator iterator = productServiceLoader.iterator();
 while (iterator.hasNext()){
      Product product = iterator.next();
      product.use();
}

运行结果:
call
eat
    ServiceLoader是JDK自带实现的SPI扫描类, 传入接口类Class信息, 然后JDK会根据接口的路径信息去扫描/meta-INF/services/com.tuling.Product文件然后将文件里面的内容一行一行全部读取出来,使用反射技术,将指定的实现类Phone,Food通过反射实例化, 放入某种数据结构容器中;

通过上面的简单例子, 差不多就可以理解SPI是个什么东西。

SPI机制的作用

步入正题, 那么JDK提供SPI机制的作用是什么呢?

    解耦与实现组件化,模块化;可以提供一套接口规范, 每个依赖包提供接口实现类,然后在/WEB-INF/services下的以接口路径命令的文件里, 指定包的实现类,项目启动的时候, 就会去扫描/WEB-INF/services下的文件,一起使用;
SPI机制常见举例

举个例子: 我们开发使用的DB操作, 一般会有Mysql, Oracle等,那么JDBC中, 有一个DriverManger类, 用来获取数据库连接;
JDBC提供了一个java.sql.Driver 接口,当我们使用不同的数据库时,各大厂商(如Mysql、Oracle)会根据一个统一的规范(java.sql.Driver)开发各自的驱动实现逻辑,客户端使用jdbc时不需要去改变代码,mysql依赖包中 /WEB-INF/services/有一个java.sql.Driver文件, 内容指定了Driver的实现类是com.mysql.jdbc.Driver, oracle依赖包中/WEB-INF/services/也有一个java.sql.Driver,内容指定了Driver的实现类是oracle.jdbc.driver.OracleDriver;

package java.sql;

import java.util.Iterator;
import java.util.ServiceLoader;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.concurrent.CopyOnWriteArrayList;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;

public class DriverManager {
    @CallerSensitive
    public static Connection getConnection(String url,
        java.util.Properties info) throws SQLException {

        return (getConnection(url, info, Reflection.getCallerClass()));
    }
    //...
}


    //  Worker method called by the public getConnection() methods.
    private static Connection getConnection(
        String url, java.util.Properties info, Class caller) throws SQLException {

        ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
        synchronized(DriverManager.class) {
            // synchronize loading of the correct classloader.
            if (callerCL == null) {
                callerCL = Thread.currentThread().getContextClassLoader();
            }
        }

        if(url == null) {
            throw new SQLException("The url cannot be null", "08001");
        }

    
        for(DriverInfo aDriver : registeredDrivers) {
            // If the caller does not have permission to load the driver then
            // skip it.
            if(isDriverAllowed(aDriver.driver, callerCL)) {
                try {
                    println("    trying " + aDriver.driver.getClass().getName());
                    Connection con = aDriver.driver.connect(url, info);
                    if (con != null) {
                        // Success!
                        return (con);
                    }
                } catch (SQLException ex) {
                    if (reason == null) {
                        reason = ex;
                    }
                }

            } else {
                println("    skipping: " + aDriver.getClass().getName());
            }

        }
    }

for(DriverInfo aDriver : registeredDrivers) 循环中的registeredDrivers代表的就是所有的Driver实现类,再根据每个驱动Driver实现类去连接具体的数据库;
而我们项目中可以一次引入mysql,oracle等多种数据库, 只需要在Mybatis的配置文件中指定使用哪种数据库, 进而再获取连接的时候,创建相关数据库的连接;

Java SPI机制的特点

优点:

    插件化模块化

缺点:

    不够灵活;
    只可以获取所有的 规范实现, 做不到只获取部分规范实现;
    项目可能使用10种数据库,就需要导入10种数据库包,我们短时间内只用到了3种 他就会将10种数据库的规范实现Driver全部扫描进来, 而不能只获取3种;
总结

Dubbo的SPI扩展机制就是对Java SPI机制的扩展, 使其更加灵活可用;

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/741831.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号