摘要:之前研究过dubbo、spring源码。然后发现大量使用一个叫做spi的东西,发现这确实是一个很好的实现方法,特别是在设计框架中。
一、SPI机制概念
SPI的全称是Service Provider Interface。简单来说,SPI机制提供了一个表达接口和其具体实现类之间的绑定关系的方案。具体是在JAR包的"META-INF/services/"目录下建立一个文件,文件名是接口的全限定名,文件的内容可以有多行,每行都是该接口对应的具体实现类的全限定名。SPI可以理解是为接口寻找服务实现类。现在公司的系统都是进行了模块的划分,系统抽象为多个模块,往往有很多不同的实现方案,比如日志模块的方案,xml解析模块、jdbc模块的方案等。面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。于是就有了SPI这种服务发现机制。
二、JDBC中的SPI机制
在java中,Java.sql.Driver接口是Java对外公开的一个加载驱动接口,Java并未实现,至于实现这个接口由各个Jdbc厂商去实现就行了,好处是解藕,使得更具有灵活性,当然这也是面向对象的好处之一。真正的实现是不同提供商提供的。
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");
Class.forName("com.mysql.jdbc.Driver");这里虽是加载mysql的driver,但是无论是oracle还是其它的jdbc驱动包,它们的原理都是spi机制。
首先看java.sql.driver
package java.sql;
import java.util.logging.Logger;
public interface Driver {
boolean acceptsURL(String url) throws SQLException;
DriverPropertyInfo[] getPropertyInfo(String url, java.util.Properties info)
throws SQLException;
int getMinorVersion();
boolean jdbcCompliant();
public Logger getParentLogger() throws SQLFeatureNotSupportedException;
}
这个类是一个接口类, 在整个JDK包中都没有它的实现类,它的实现要由各个jdbc的开发产商去实现,但是我们发现DriverManager这个类中还是有去加载Driver类