Java SPI
程序员文章站
2022-07-09 13:42:33
...
SPI是什么
SPI,该机制的理解是为接口寻找服务实现类。比如Mysql,在java中并没有对Mysql、Oracle驱动实现。只提供了一个java.sql.Driver接口,来让数据库厂商各自实现。大家不妨看看Mysql驱动的源码。
自定义实现:
当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。
基于这样一个约定就能很好的找到服务接口的实现类,而不需要再代码里制定。
案例:
接口:
package com.test.spi;
public interface Developer {
public String getValue();
}
实现类
package com.test.spi;
public class JavaDeveloper implements Developer {
@Override
public String getValue() {
return "Java";
}
}
package com.test.spi;
public class PythonDeveloper implements Developer {
@Override
public String getValue() {
return "Python";
}
}
META-INF\services文件下的com.test.spi.Developer文件内容是实现类的全限命名:
com.test.spi.JavaDeveloper
com.test.spi.PythonDeveloper
测试类:
package com.test.spi;
import java.util.ServiceLoader;
import com.test.spi.Developer;
public class Test {
public static ServiceLoader<Developer> serviceloader = ServiceLoader.load(Developer.class);
public static void main(String[] arg) {
for (Developer dev : serviceloader) {
System.out.println("语言:" + dev.getValue());
}
}
}
开发中都有用到SPI机制:
1.common-logging
apache只提供了接口。具体方案由各提供商实现,
日志提供商是通过扫描META-INF/services/org.apache.commons.logging.LogFactory配置文件,
通过读取该文件的内容找到日志提工商实现类。只要我们的日志实现里包含了这个文件,并在文件里制定LogFactory工厂接口的实现类即可。
2.jdbc
jdbc4.0以前,开发人员还需要基于Class.forName(“xxx”)的方式来装载驱动,jdbc4也基于spi的机制来发现驱动提供商了,可以通过META-INF/services/java.sql.Driver文件里指定实现类的方式来暴露驱动提供者。