SPI:Service Provider Interface
自身只定义接口,通过其他jar来提供实现,从而可以实现jar包替换后即可执行,实现IoC,可用于plugins/modules。
(1)Java Service Loader
JDK 6开始提供java.util.ServiceLoader
https://docs.oracle.com/javase/tutorial/ext/basics/spi.html
https://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html
定义实现类
META-INF/services/[InterfaceFQCN]
比如:
META-INF/services/com.rensanning.spi.Sample
引用
com.rensanning.spi.SampleImpl1 # comment1
com.rensanning.spi.SampleImpl2 # comment2
-可以定义多行,一行一个实现(多个实现具体如何用是在程序内部控制的)
-#号开头的是注释
-必须UTF-8编码(避免使用非英语字符)
获取实现类
ServiceLoader<Sample> loader = ServiceLoader.load(Sample.class);
for (Sample provider: loader) {
// ...
}
-默认采用的是当前线程的类加载器(Thread Context Classloader)
-可以自己指定类加载器:ServiceLoader.load(Sample.class, ClassLoader.getSystemClassLoader());
-ServiceLoader只能通过无参构造函数对服务实例
-ServiceLoader返回一个Iterator对象对服务实例懒加载,只有调用next()方法时才会实例化下一个服务实例
集成Spring
@Configuration
public class ServiceConfiguration {
@Bean
public ServiceListFactoryBean serviceListFactoryBean() {
ServiceListFactoryBean serviceListFactoryBean = new ServiceListFactoryBean();
serviceListFactoryBean.setServiceType(Sample.class);
return serviceListFactoryBean;
}
}
Object object = serviceListFactoryBean.getObject();
JDK1.5通过sun.misc.Service(未公开的API)来加载。
Iterator<Sample> i = Service.providers(Sample.class);
while (i.hasNext()) {
Sample s = i.next();
// ...
}
-其实META-INF/services是JDK 1.3开始就有的“Java Extension Mechanism”
最典型的2个应用:JDBC、Logger
JDBC
JDBC4 定义了接口java.sql.Driver,具体实现可以是MySQL、PostgreSQL等
mysql-connector-java-5.1.22-bin.jar/META-INF/services/java.sql.Driver
引用
com.mysql.jdbc.Driver
postgresql-9.4-1201-jdbc4.jar/META-INF/services/java.sql.Driver
引用
org.postgresql.Driver
java.sql.DriverManager在初始化的时候会主动加载这些驱动类,不需要Class.forName()。
ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
Logger
可以通过实现来切换JUL,Logback, Log4J等
SLF4J 定义了接口org.slf4j.Logger,但还不支持SPI,仍采用的是StaticLoggerBinder来实现的。
https://jira.qos.ch/browse/SLF4J-227
JBoss Logging:META-INF/services/org.jboss.logging.LoggerProvider
common-logging:META-INF/services/org.apache.commons.logging.LogFactory
OSGi 和 SPI之间还有些纠纷,具体可以看看这里:
http://blog.osgi.org/2013/02/javautilserviceloader-in-osgi.html
(2)Spring Factories Loader
Spring自己实现了一个类似于属性文件的配置文件:
META-INF/spring.factories
http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/io/support/SpringFactoriesLoader.html
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/serviceloader/package-summary.html
比如:
spring-boot-autoconfigure-1.5.2.RELEASE.jar/META-INF/spring.factories
引用
# Template availability providers
org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.web.JspTemplateAvailabilityProvider
org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders
List<TemplateAvailabilityProvider> providers = SpringFactoriesLoader.loadFactories(TemplateAvailabilityProvider.class, classLoader);
参考:
https://dzone.com/articles/java-service-loader-vs-spring-factories-loader
http://stackoverflow.com/questions/2954372/difference-between-spi-and-api
分享到:
相关推荐
java spi 可运行 demo
提供JAVA SPI实现的简单例程, 希望能有用。
这个资源是我的博客《java SPI机制学习笔记》中的提供服务的jar包
演示如何用java SPI来做一个类似插件系统。无需任何IDE,只要有JDK即可。命令行操作,无公害。
java spi简单参考,url:https://blog.csdn.net/a925907195/article/details/87088744 主类:testcase,代码很简单,只是自己写个demo看看运行原理
这个jar包用来解析MP3的音频文件,可以使用java的sound包中的类进行播放MP3音频文件
Java SPI 机制(SPI实战+ServiceLoader源码分析+SPI 应用场景+破坏双亲委派)
java的spi测试,主要是两个接口的实现类和demo。。。。。
Java类加载及SPI机制.pdf
java 干旱SPI逐日计算 90天150天,基于mysql表
java mp3spi jar java 处理mp3 jar 包
Java SPI机制详解.md
JAVA SPI原理源码详细介绍,MD格式,有大纲目录
主要介绍了Java SPI的简单小实例,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
spi-示例.rar
该项目主要用来演示通过 Java SPI 和 Spring factories 两种方式来实现插件化
java中的Spi使用实例,详情请见文章http://blog.csdn.net/evankaka/article/details/58265019
如何拼写 SPI(服务提供者接口)? 用 Java 编程语言编写的服务可以由不同的服务提供者实现。 虽然服务通常是用接口或抽象类编写的,但服务提供者是实现这些接口服务的实现类。 java.util.ServiceLoader类从 Java...
在本篇文章里小编给大家整理的是一篇关于Java SPI 机制知识点总结内容,需要的朋友们可以参考下。