详解JAVA SPI机制和使用方法
java spi 简介
spi 是 java 提供的一种服务加载方式,全名为 service provider interface。根据 java 的 spi 规范,我们可以定义一个服务接口,具体的实现由对应的实现者去提供,即服务提供者。然后在使用的时候再根据 spi 的规范去获取对应的服务提供者的服务实现。通过 spi 服务加载机制进行服务的注册和发现,可以有效的避免在代码中将具体的服务提供者写死。从而可以基于接口编程,实现模块间的解耦。
spi 机制的约定
1 在 meta-inf/services/ 目录中创建以接口全限定名命名的文件,该文件内容为api具体实现类的全限定名
2 使用 serviceloader 类动态加载 meta-inf 中的实现类
3 如 spi 的实现类为 jar 则需要放在主程序 classpath 中
4 api 具体实现类必须有一个不带参数的构造方法
spi 应用场景举例
jdbc
jdbc4.0以前, 开发人员还需要基于class.forname("xxx")的方式来装载驱动,jdbc4也基于spi的机制来发现驱动提供商了,可以通过metainf/services/java.sql.driver文件里指定实现类的方式来暴露驱动提供者.
common-logging
apache最早提供的日志的门面接口。只有接口,没有实现。具体方案由各提供商实现, 发现日志提供商是通过扫描metainf/services/org.apache.commons.logging.logfactory配置文件,通过读取该文件的内容找到日志提工商实现类。只要我们的日志实现里包含了这个文件,并在文件里制定 logfactory工厂接口的实现类即可。
spi 机制代码示例
接口 people.java
package org.louis.spi.test; public interface people { public string speak(); }
实现类 chinese.java
package org.louis.spi.test; public class chinese implements people{ public string speak() { return "chinese speak chinese."; } }
实现类 american.java
package org.louis.spi.test; public class american implements people{ public string speak() { return "american speak english."; } }
创建一个文件,放置到 meta-inf/services 目录:
文件名:org.louis.spi.test.people
文件内容:
org.louis.spi.test.chinese org.louis.spi.test.american
新建一个测试工程,引入以上代码生成的jar包
测试类spitest.java
package org.louis.test; import java.util.iterator; import java.util.serviceloader; import org.louis.spi.test.people; import org.louis.spi.test.chinese; import org.louis.spi.test.american; public class spitest { public static void main(string[] args) { serviceloader<people> peoples = serviceloader.load(people.class); iterator<ioperation> iterator = peoples.iterator(); while (iterator.hasnext()) { people people = iterator.next(); system.out.println(people.speak()); } } }
运行结果:
chinese speak chinese.
american speak english.
通过上面例子,我们看到,假如我要新加入一个韩国人的实现,那只需要新建一个新的工程,创建一个koeran类实现people接口,并在自己工程 meta-inf/services 目录下放置一个配置文件指定koeran实现类,将工程打成jar包,就完成了一个新的服务实现的开发。
以上就是示例讲解java spi机制的详细内容,更多关于java spi机制的资料请关注其它相关文章!