Java提供的Service Provider机制其实就是一种DI,在实现时只考虑接口(也就是规范),由其他第三方去实现具体的功能。这个跟Spring的依赖注入概念上差不多,Spring是框架级别的依赖注入,SPI则是语言自身提供的,不依赖于任何框架。
具体使用方法非常简单,假设系统中实现一个接口,例如com.test.DemoInterface,由第三方提供具体实现,有以下步骤:
1. 第三方提供DemoInterface的实现类,例如com.test.thirdparty.DemoInterfaceImpl
2. 在生成的jar包里,在META-INF/services目录下,创建一个UTF-8编码的文件,名称为com.test.DemoInterface,然后内容只需要一行,就是实现类的全路径 (com.test.thirdparty.DemoInterfaceImpl)
3. 在系统中使用以下代码即可调用
ServiceLoader<DemoInterface> di = ServiceLoader.load(DemoInterface.class);
需要注意的是,di拿到的结果里,providers列表默认为空,也就是ServiceLoader只是去加载类,但并没有实例化,只有当第一次使用后,列表里才会有记录。
Iterator<DemoInterface> ite = di.iterator(); while (ite.hasNext()) { System.out.println(ite.next()); }
调用完以上代码后,再去di里查看,providers列表有值了。
这里涉及一个问题就是,如果有多个第三方jar都提供了实现,并且都有META-INF/services的文件,系统加载到的列表的优先顺序如何呢?
默认情况下,系统会按照jar包加载的顺序来排序,也就是先发现的排在最前面(这里大致提一下jar包的加载顺序,默认情况下是: 系统/应用本身的类文件以及classpath --> 系统/应用本身引用的jar包 --> 应用服务器的jar包),如果有2个jar包,01.jar和02.jar,默认情况下01.jar会优先于02.jar的加载(其实也就是默认按照文件管理器里的排序顺序来加载的)。
如果希望优先加载02.jar,只要在启动应用时,手动指定classpath里jar的顺序就可以了,或者把02.jar改名为00.jar。也就是说可以通过修改jar包的名称来改变加载顺序。
然后我们在实现系统时,大多数情况下,只需要取得第一个实现就可以了。
Jaxb里在实例化XmlOutputFactory时,就使用这种方式,使用抽象工厂的方式加载对应的Xml工厂类,只是在查找方式上更加多样化一些,实际项目实施时可以考虑。
那里面有一个FactoryFinder,在寻找具体实现的工厂类时,按照以下顺序查找:
1. 查找SystemProperty里有没有指定,有则返回
2. 查找指定目录下的某个配置文件,如果有指定,则返回
3. 使用Java Service Provider机制查找
附件有这2个类的参考代码,就是从Jaxb里搬来的。
相关推荐
File System Service Provider,文件系统服务提供者,JAVA SE中使用JNDI时常用
Java Print Service (JPS)是一个Java打印API,设计此API是为了支持在所有Java平台上的打印工作——包括微空间平台,并且支持现有的API。这个统一的打印 API包括了IETF规范RFC 2911中Internet Printing Protocol (IPP...
Android SM2、SM3、SM4 算法支持 Service Provider 及证书制作软件包 国密算法 JCAJCE Service Provider,适应版本 Android 4.2.2~7.0 支持 SM2 的 KeyFactory、KeyPairGenerator、Cipher、Signature、X.509 ...
SPI(Service Provider Interface)是 Java 中一种基于接口的服务发现机制,旨在实现代码解耦和可扩展性。通过 SPI,开发者可以定义一组接口,而具体的实现则由不同的提供者来提供,实现了解耦的目的。 SPI 机制使得...
JMS Java Message Service Java消息服务。是JAVA EE中的一个技术,JMS定义了JAVA中访问消息中间件的接口。类似JDBC。定义了接口,并不具体实现。实现JMS接口消息的中间件称为JMS Provider.
服务提供者Service Provider 是用于远程客户端测试的各种服务(REST、WS、JMS、EJB 等)的 Java EE 应用程序。可用的 REST 服务 (JAX-RS) 网址: AcronymsDictionary - /acronym 回声 - /回声HttpStatus - /status ...
Java Enterprise应用程序通过异构服务处理多个用户启动的SMS消息,提供了高性能和安全性。 使用的主要技术:JMS,EJB,JTA,SMPP,TCP / IP。
Movie Points (Java Message Service 2) Conclusion Troubleshooting Completed Solution Appendix : Further Reading Web Technology Specifications Enterprise Technology Specifications Web ...
服务提供者-服务提供者 PiDev服务提供商
see Sun PKCS#11 Provider's Supported Algorithms in Java PKCS#11 Reference Guide. Weak cryptographic algorithms can now be disabled; see Appendix D: Disabling Cryptographic Algorithms in Java PKI ...
SPI的全称是Service Provider Interface,是Java提供的可用于第三方实现和扩展的机制,通过该机制,我们可以实现解耦,SPI接口方负责定义和提供默认实现,SPI调用方可以按需扩展 API的全称是Application ...
Represents the Service Provider Interface (SPI) for java.security.Policy class.
本项目是一个基于Spring Boot框架开发的东理咨询交流论坛项目,使用了JSPM(Java Service Provider Modules)技术来实现模块化设计。论坛主要包括用户管理、帖子管理、评论管理等功能模块,旨在为东理学子提供一个...
oiosaml-proxy(jar版本)
Provider 2、大家应该知道,AngularJS是后台人员在工作之余发明的,他主要应用了后台早就存在的分层思想。所以我们得了解下分层的作用,如果你是前端人员不了解什么是分层,那么你最好问问你后台的小伙伴。 dao层...
JAVA学习资料思维导图,主要包括以下内容: 一、JAVA部分 1、GUI(Abstract Window Tookit).mmap 2、Java中的注解.mmap 3、Java网络编程.mmap 4、Java中的反射.mmap 5、Java中级总结.mmap ...4、Content Provider.mmap
本包主要用来生成Java后端代码包括bean、service、impl 、sql 常见CRUD操作等 同时包括附加其他工具类亲测有效