`
rensanning
  • 浏览: 3549219 次
  • 性别: Icon_minigender_1
  • 来自: 大连
博客专栏
Efef1dba-f7dd-3931-8a61-8e1c76c3e39f
使用Titanium Mo...
浏览量:38163
Bbab2146-6e1d-3c50-acd6-c8bae29e307d
Cordova 3.x入门...
浏览量:607345
C08766e7-8a33-3f9b-9155-654af05c3484
常用Java开源Libra...
浏览量:682380
77063fb3-0ee7-3bfa-9c72-2a0234ebf83e
搭建 CentOS 6 服...
浏览量:89388
E40e5e76-1f3b-398e-b6a6-dc9cfbb38156
Spring Boot 入...
浏览量:401869
Abe39461-b089-344f-99fa-cdfbddea0e18
基于Spring Secu...
浏览量:69706
66a41a70-fdf0-3dc9-aa31-19b7e8b24672
MQTT入门
浏览量:91732
社区版块
存档分类
最新评论

关于Java SPI

    博客分类:
  • Java
 
阅读更多
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实现工程

    Java SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许JVM在运行时动态加载服务提供商。这个机制使得开发者可以扩展应用的功能,而无需修改原有代码。SPI的核心概念在于,服务接口由主程序...

    java spi 可运行 demo

    Java SPI(Service Provider Interface)是Java标准库提供的一种服务发现机制,它允许程序在运行时动态地查找并加载实现特定接口的服务提供商。SPI的核心概念在于将服务接口与其实现类解耦,使得开发者可以在不修改...

    java SPI的jar包

    这个资源是我的博客《java SPI机制学习笔记》中的提供服务的jar包

    Java SPI Demo

    Java SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许JVM在运行时动态加载和使用服务提供商。这个机制使得开发者可以扩展应用程序的功能,而不需要修改应用程序的代码。在Java SPI中,...

    Java SPI 机制(SPI实战+ServiceLoader源码分析+SPI 应用场景+破坏双亲委派)

    Java SPI 机制详解 Java SPI 机制,全称 Service Provider Interface,是 Java 内置的服务发现机制。SPI 机制的主要思想是解耦,通过提供一个标准接口,允许第三方提供实现类,而无需在程序中硬编码。SPI 机制广泛...

    java对于MP3的spi

    Java平台扩展机制(Service Provider Interface, SPI)是一种允许第三方开发者扩展Java应用程序或库的功能的方式。在Java Sound API中,SPI扮演着关键角色,使得开发者能够添加对不同音频格式的支持,如MP3。MP3 SPI...

    java-mp3spi

    Java MP3SPI,全称Java Media Framework (JMF) MP3 Service Provider Interface,是一个用于在Java平台上处理MP3音频文件的扩展库。它基于Java Media Framework (JMF),提供了对MP3格式音频流的支持,使得Java开发者...

    java的spi测试

    Java的Service Provider Interface (SPI) 是一种用于在运行时动态发现和加载服务提供者实现的机制。这个功能在Java标准库中被广泛使用,允许开发者扩展JVM的功能,而无需修改核心API。在这个"java的spi测试"中,我们...

    spi-demo java spi小例子

    java spi简单参考,url:https://blog.csdn.net/a925907195/article/details/87088744 主类:testcase,代码很简单,只是自己写个demo看看运行原理

    java mp3spi jar

    java mp3spi jar java 处理mp3 jar 包

    java spi 学习记录

    Java SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许JVM在运行时动态加载和使用服务提供商。SPI机制使得开发者可以扩展程序的功能,而无需修改原代码,极大地提高了软件的可扩展性和模块...

    java spi-demo示例

    Java SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许JVM在运行时动态加载和使用服务提供商。SPI机制使得开发者可以扩展程序的功能,而无需修改原代码,极大地提高了软件的可扩展性和模块...

    java代码 干旱SPI逐日计算,基于mysql数据库

    在Java编程环境中,开发一个基于MySQL数据库的SPI计算系统,可以有效地处理和分析大量的气象数据。 首先,我们需要了解SPI计算的基本原理。SPI是通过对历史降水数据进行统计转换得出的,通常采用经验累积概率分布...

    java-spi学习例子

    Java SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许JVM在运行时动态加载服务实现。这个机制使得开发者可以扩展已存在的应用程序或库,而无需修改原代码。SPI的核心理念是将服务接口与其...

    Java类加载及SPI机制.pdf

    Java类加载机制和SPI(ServiceProviderInterface)机制是Java平台中极其重要的两个概念,它们对于Java程序的灵活性和可扩展性起到关键作用。下面详细解释这两个机制的概念、原理和应用场景。 类加载机制是Java...

    Java SPI的简单小实例

    Java SPI的简单小实例 Java SPI(Service Provider Interface)是一种Java标准机制,允许应用程序在运行时发现和加载服务提供者。Java SPI的主要思想是将服务接口和服务实现分离,使得服务实现可以独立于服务接口...

    Java的Spi使用实例

    Java SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许JVM在运行时动态加载服务实现。这个机制使得开发者能够将核心功能模块化,然后由其他开发者提供不同的实现来扩展系统功能。SPI的核心...

    java SPI机制实现服务接口和服务实现分离源码Demo

    Java SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许JVM在运行时动态加载服务实现。这种机制使得应用程序能够与多个第三方组件进行交互,而无需在编译时硬编码具体的实现类。SPI机制的...

    Java SPI机制详解.md

    Java SPI机制详解.md

    采用Java SPI和Spring factories来实现插件化的demo

    Java SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许第三方开发者为Java应用程序提供扩展服务。Spring Factories则是Spring框架中用于自动配置和服务发现的一种机制,它基于类路径下的...

Global site tag (gtag.js) - Google Analytics