SPI与API

栏目: Java · 发布时间: 7年前

内容简介:SPI与我们熟知的API名字上有点相似,SPI被称为服务提供接口,API称为应用程序接口,两者的区别大致可以这样来对比。 假设有客户方和服务方,彼此通过约定的接口对接。我们平时最常见的SPI服务就是JDBC。通过统一的JDBC规范,客户方可以自己实现各种数据源。试想一下,假设开发者想将数据源从Mysql切换到Oracle,如果没有使用JDBC,切换的过程就需要耗费巨大的人力成本。如何解决上述的数据源切换问题,这里需要说一下依赖倒置原则。

SPI与我们熟知的API名字上有点相似,SPI被称为服务提供接口,API称为应用程序接口,两者的区别大致可以这样来对比。 假设有客户方和服务方,彼此通过约定的接口对接。

  1. 服务方暴露自己的业务供客户方调用,则为提供API服务。
  2. 客户方实现服务方提供的接口,然后让服务方去调用自己,则为提供SPI服务。
SPI与API

我们平时最常见的SPI服务就是JDBC。通过统一的JDBC规范,客户方可以自己实现各种数据源。试想一下,假设开发者想将数据源从 Mysql 切换到Oracle,如果没有使用JDBC,切换的过程就需要耗费巨大的人力成本。

如何解决上述的数据源切换问题,这里需要说一下依赖倒置原则。

  1. 高层模块不应该依赖低层模块,两者都应该依赖抽象
  2. 抽象不应该依赖细节
  3. 细节应该依赖抽象

JDBC连接Mysql

Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(
              "jdbc:mysql://localhost:3306/test", "root", "123456");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from Users");
复制代码

下面自己实现一个简易版的JDBC程序。 驱动管理程序,负责加载各SPI服务,用一个Map保存所有加载过的驱动程序,key为SPI服务自定义的名称。在调用connection时,只要url中的前缀为驱动名,则使用该驱动创建连接。

/**
 * 驱动管理,负责加载各客户方提供的数据源服务/
 */
public class MyDriverManager {
   /**
     * 所有注册的数据源连接服务/
    */
private static final Map<String, MyDriver> registerDriver = new HashMap<String, MyDriver>();

    public static void registerDriver(String name, MyDriver driver) {
        registerDriver.put(name, driver);
    }

    public static MyConnection getConnection(String url) {
        for (String key : registerDriver.keySet()) {
            if (url.startsWith(key)) {
                return registerDriver.get(key).getConnection(url);
            }
        }
        throw new RuntimeException("no such provider");
    }
}

复制代码

定义驱动接口

public interface MyDriver {
		/**
		 * 获取连接
		 */
		MyConnection getConnection(String url);
}
复制代码

客户方自己实现的驱动程序,静态代码块中执行注册服务,将驱动注册到驱动管理程序中。

public class MysqlDriver implements MyDriver {

    static {
        MyDriverManager.registerDriver(“mysql”, new MysqlDriver());
    }

    public MyConnection getConnection(String url) {
        System.out.println(“connect to mysql: url = “ + url);
        return new MysqlConnection();
    }
}
复制代码

实际执行时,要先使用Class.forName加载一下驱动程序,否则static代码块不会执行,无法将驱动加载到驱动管理程序中。

public class Main {

    public static void main(String[] args) throws ClassNotFoundException {
        		 Class.forName(“com.github.yaolang.chapter01.spi1.MysqlDriver”);
        MyConnection myConnection = MyDriverManager.getConnection(“mysql://localhost:8080”);
        System.out.println(myConnection);
    }
}
复制代码

以下为输出结果

connect to mysql: url = mysql://localhost:8080
com.github.yaolang.chapter01.spi1.MysqlConnection@60e53b93
复制代码

以上所述就是小编给大家介绍的《SPI与API》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

About Face 3

About Face 3

Alan Cooper、Robert Reimann、David Cronin / John Wiley & Sons / 2007-5-15 / GBP 28.99

* The return of the authoritative bestseller includes all new content relevant to the popularization of how About Face maintains its relevance to new Web technologies such as AJAX and mobile platforms......一起来看看 《About Face 3》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具