详解JAVA SPI机制和使用方法
JAVASPI简介
SPI是Java提供的一种服务加载方式,全名为ServiceProviderInterface。根据Java的SPI规范,我们可以定义一个服务接口,具体的实现由对应的实现者去提供,即服务提供者。然后在使用的时候再根据SPI的规范去获取对应的服务提供者的服务实现。通过SPI服务加载机制进行服务的注册和发现,可以有效的避免在代码中将具体的服务提供者写死。从而可以基于接口编程,实现模块间的解耦。
SPI机制的约定
1在META-INF/services/目录中创建以接口全限定名命名的文件,该文件内容为API具体实现类的全限定名
2使用ServiceLoader类动态加载META-INF中的实现类
3如SPI的实现类为Jar则需要放在主程序ClassPath中
4API具体实现类必须有一个不带参数的构造方法
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
packageorg.louis.spi.test; publicinterfacePeople{ publicStringspeak(); }
实现类Chinese.java
packageorg.louis.spi.test; publicclassChineseimplementsPeople{ publicStringspeak(){ return"ChinesespeakChinese."; } }
实现类American.java
packageorg.louis.spi.test; publicclassAmericanimplementsPeople{ publicStringspeak(){ return"AmericanspeakEnglish."; } }
创建一个文件,放置到META-INF/Services目录:
文件名:org.louis.spi.test.People
文件内容:
org.louis.spi.test.Chinese org.louis.spi.test.American
新建一个测试工程,引入以上代码生成的Jar包
测试类SpiTest.java
packageorg.louis.test; importjava.util.Iterator; importjava.util.ServiceLoader; importorg.louis.spi.test.People; importorg.louis.spi.test.Chinese; importorg.louis.spi.test.American; publicclassSpiTest{ publicstaticvoidmain(String[]args){ ServiceLoaderpeoples=ServiceLoader.load(People.class); Iterator iterator=peoples.iterator(); while(iterator.hasNext()){ Peoplepeople=iterator.next(); System.out.println(people.speak()); } } }
运行结果:
ChinesespeakChinese.
AmericanspeakEnglish.
通过上面例子,我们看到,假如我要新加入一个韩国人的实现,那只需要新建一个新的工程,创建一个Koeran类实现People接口,并在自己工程META-INF/Services目录下放置一个配置文件指定Koeran实现类,将工程打成Jar包,就完成了一个新的服务实现的开发。
以上就是示例讲解JAVASPI机制的详细内容,更多关于JAVASPI机制的资料请关注毛票票其它相关文章!