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(Service Provider Interface)是Java平台提供的一种服务发现机制,允许JVM在运行时动态加载服务提供商。这个机制使得开发者可以扩展应用的功能,而无需修改原有代码。SPI的核心概念在于,服务接口由主程序...
Java SPI(Service Provider Interface)是Java标准库提供的一种服务发现机制,它允许程序在运行时动态地查找并加载实现特定接口的服务提供商。SPI的核心概念在于将服务接口与其实现类解耦,使得开发者可以在不修改...
这个资源是我的博客《java SPI机制学习笔记》中的提供服务的jar包
Java SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许JVM在运行时动态加载和使用服务提供商。这个机制使得开发者可以扩展应用程序的功能,而不需要修改应用程序的代码。在Java SPI中,...
Java SPI 机制详解 Java SPI 机制,全称 Service Provider Interface,是 Java 内置的服务发现机制。SPI 机制的主要思想是解耦,通过提供一个标准接口,允许第三方提供实现类,而无需在程序中硬编码。SPI 机制广泛...
Java MP3SPI,全称Java Media Framework (JMF) MP3 Service Provider Interface,是一个用于在Java平台上处理MP3音频文件的扩展库。它基于Java Media Framework (JMF),提供了对MP3格式音频流的支持,使得Java开发者...
Java的Service Provider Interface (SPI) 是一种用于在运行时动态发现和加载服务提供者实现的机制。这个功能在Java标准库中被广泛使用,允许开发者扩展JVM的功能,而无需修改核心API。在这个"java的spi测试"中,我们...
java spi简单参考,url:https://blog.csdn.net/a925907195/article/details/87088744 主类:testcase,代码很简单,只是自己写个demo看看运行原理
Java平台扩展机制(Service Provider Interface, SPI)是一种允许第三方开发者扩展Java应用程序或库的功能的方式。在Java Sound API中,SPI扮演着关键角色,使得开发者能够添加对不同音频格式的支持,如MP3。MP3 SPI...
java mp3spi jar java 处理mp3 jar 包
Java SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许JVM在运行时动态加载和使用服务提供商。SPI机制使得开发者可以扩展程序的功能,而无需修改原代码,极大地提高了软件的可扩展性和模块...
Java SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许JVM在运行时动态加载和使用服务提供商。SPI机制使得开发者可以扩展程序的功能,而无需修改原代码,极大地提高了软件的可扩展性和模块...
在Java编程环境中,开发一个基于MySQL数据库的SPI计算系统,可以有效地处理和分析大量的气象数据。 首先,我们需要了解SPI计算的基本原理。SPI是通过对历史降水数据进行统计转换得出的,通常采用经验累积概率分布...
Java SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许JVM在运行时动态加载服务实现。这个机制使得开发者可以扩展已存在的应用程序或库,而无需修改原代码。SPI的核心理念是将服务接口与其...
Java类加载机制和SPI(ServiceProviderInterface)机制是Java平台中极其重要的两个概念,它们对于Java程序的灵活性和可扩展性起到关键作用。下面详细解释这两个机制的概念、原理和应用场景。 类加载机制是Java...
Java SPI的简单小实例 Java SPI(Service Provider Interface)是一种Java标准机制,允许应用程序在运行时发现和加载服务提供者。Java SPI的主要思想是将服务接口和服务实现分离,使得服务实现可以独立于服务接口...
Java SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许JVM在运行时动态加载服务实现。这个机制使得开发者能够将核心功能模块化,然后由其他开发者提供不同的实现来扩展系统功能。SPI的核心...
Java SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许JVM在运行时动态加载服务实现。这种机制使得应用程序能够与多个第三方组件进行交互,而无需在编译时硬编码具体的实现类。SPI机制的...
Java SPI机制详解.md
Java SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许第三方开发者为Java应用程序提供扩展服务。Spring Factories则是Spring框架中用于自动配置和服务发现的一种机制,它基于类路径下的...