目录
概念
JDBC实例
自己实现一个SPI
总结
概念 英文:
What is the difference between Service Provider Interface (SPI) and Application Programming Interface (API)?
More specifically, for Java libraries, what makes them an API and/or SPI?
the API is the description of classes/interfaces/methods/... that you call and use to achieve a goal
the SPI is the description of classes/interfaces/methods/... that you extend and implement to achieve a goal
【JAVA—API和SPI概念】Put differently, the API tells you what a specific class/method does for you and the SPI tells you what you must do to conform.
Sometimes SPI and API overlap. For example in JDBC the Driver class is part of the SPI: If you simply want to use JDBC, you don't need to use it directly, but everyone who implements a JDBC driver must implement that class.
The Connection interface on the other hand is both SPI and API: You use it routinely when you use a JDBC driver and it needs to be implemented by the developer of the JDBC driver.
大致含义:
服务提供接口(SPI)和应用程序接口(API)有什么不同?
具体来说,在JAVA类库中,是什么组成了API或者SPI?
API是你可以调用或者使用类/接口/方法等去完成某个目标的意思。
SPI是你需要继承或实现某些类/接口/方法等去完成某个目标的意思。
换句话说,API制定的类/方法可以做什么,而SPI告诉你你必须符合什么规范。
有时候SPI和API互相重叠。例如JDBC驱动类是SPI的一部分:如果仅仅是想使用JDBC驱动,你不需要实现这个类,但如果你想要实现JdBC驱动那就必须实现这个类。
关于SPI和API:你使用JDBC驱动时可以使用现成的,该驱动由需要JDBC驱动开发者实现。
概括:
API:API由开发人员调用。
SPI:SPI是框架接口规范,需要框架开发人员实现。
JDBC实例
1.Class.forName("com.mysql.jdbc.Driver");
2.Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/test", "root", "123456");
3.Statement stmt = conn.createStatement();
4.ResultSet rs = stmt.executeQuery("select * from Users");
步骤2、3、4可以看做是API的调用。而DriverManager、Conn的编写则可以看做是SPI,实现制定的接口。
自己实现一个SPI 现在我们来实现一个如JDBC加载驱动这样模式的实例,我们定义一个消息驱动接口,实现并调用该驱动API。
消息驱动接口:
public interface IMsg {
//发送消息,打印到控制台
void send(String msg);
}
消息驱动管理:
用来根据不同消息驱动的实现,获得不同驱动。
public class MsgManage {private static final Map> map = new HashMap>();
public static void register(String protocol, Class extends IMsg> cls) {
map.put(protocol, cls);
}public IMsg getMsgConnection(String protocol) {
try {
return map.get(protocol).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
实现MyMsg消息驱动类:
public class MyMsg implements IMsg{static {
MsgManage.register("my", MyMsg.class);
}public void send(String msg) {
System.out.println("[通过MyMsg实现加载]" + msg);
}
}
实现YourMsg消息驱动类:
public class YourMsg implements IMsg{static {
MsgManage.register("your", YourMsg.class);
}public void send(String msg) {
System.out.println("[通过YourMsg实现加载]" + msg);
}
}
调用:
public class SpiD {@Test
public void test() throws ClassNotFoundException {
Class.forName("com.owl.zookeeper.use.spi.MyMsg");
Class.forName("com.owl.zookeeper.use.spi.YourMsg");
IMsg my = new MsgManage().getMsgConnection("my");
IMsg your = new MsgManage().getMsgConnection("your");
my.send("你好,世界");
your.send("你好,世界");
}
}
输出:
[通过MyMsg实现加载]你好,世界
[通过YourMsg实现加载]你好,世界
总结 可以看出API主要是指调用已经实现的类去完成工作,使用者主要是程序开发人员。SPI主要是指框架扩展的规范,实现该规范可以扩展你框架的功能,使用者主要是框架开发人员。