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扩展了JNDI的功能,使得开发者能够以统一的方式处理文件系统操作,增强了Java应用程序的灵活性和可扩展性。通过学习和熟练掌握这一技术,开发者可以更好地利用JNDI的优势,简化...
**Spring Cloud Eureka Service Provider** 是一个基于Spring Cloud框架的组件,用于实现服务发现功能。在微服务架构中,服务发现是至关重要的,它允许服务消费者找到并与其所需的服务进行通信。Eureka是Netflix开发...
Java SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许JVM在运行时动态加载服务实现。这种机制使得应用程序能够与多个第三方组件进行交互,而无需在编译时硬编码具体的实现类。SPI机制的...
CMPP2.0协议是中国移动通信集团制定的一种短消息传输协议,主要用于SP(Service Provider)与SCP(Service Control Point)之间的数据交换,支持大规模、高效、稳定地发送和接收短信。在Java环境中实现CMPP2.0协议,...
SGIP1.2协议是中国联通的一种短消息网关接口协议,用于实现SP(Service Provider,服务提供商)与SMSC(Short Message Service Center,短消息服务中心)之间的数据交换。本项目提供了一个基于Java语言的完整实现,...
Android SM2、SM3、SM4 算法支持 Service Provider 及证书制作软件包 国密算法 JCAJCE Service Provider,适应版本 Android 4.2.2~7.0 支持 SM2 的 KeyFactory、KeyPairGenerator、Cipher、Signature、X.509 ...
Java Print Service API 用户手册中文版 Java Print Service API 是一个 Java 打印 API,旨在支持在所有 Java 平台上的打印工作,包括微空间平台,并且支持现有的 API。该 API 包括了 IETF 规范 RFC 2911 中 ...
1. **CMPP协议**:CMPP协议是中国移动制定的一套基于TCP/IP的通信协议,用于SP(Service Provider)与MC(Mobile Center)之间进行数据交互。协议主要包括CMPP_SUBMIT(发送短信)、CMPP_DELIVER(接收短信)、CMPP_...
### Java Print Service (JPS) 概述 Java Print Service (JPS) 是一项重要的 Java 打印 API,旨在提供跨平台的打印解决方案,适用于所有 Java 平台,包括微型空间平台。该 API 支持现有 API 的同时,还遵循 IETF ...
新浪微博OAuth授权的Java实现 一、 OAuth协议简介 OAuth协议是一种广泛使用的授权协议,使用户不需要直接向第三方应用提供用户名及密码,且使一个账户在多个网站中使用成为可能。OAuth协议的细节描述可参考其官方...
为了提高性能,GitLab API Service Provider可能实现了缓存机制,将经常访问的数据存储在内存或磁盘中,减少不必要的网络请求。这涉及到缓存策略的选择,如LRU(Least Recently Used)或TTL(Time To Live)。 8. ...
Java SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许JVM在运行时动态加载服务提供商。这个机制使得开发者可以扩展应用的功能,而无需修改原有代码。SPI的核心概念在于,服务接口由主程序...
首先,Java认证通常涉及使用Java Authentication and Authorization Service (JAAS)框架,这是一个标准的Java API,用于实现用户认证和授权。在IBM Cognos中配置第三方Java认证,你需要创建一个定制的身份验证模块,...
CMPP是中国移动设计的一种高效、可靠的短消息传输协议,广泛应用于SP(Service Provider)与运营商之间的数据交互。通过这套源代码,开发者可以学习如何构建自己的短信服务系统,实现短信的发送、接收以及状态报告等...
3. **服务注册与暴露**:在服务提供者中,你需要配置Dubbo的XML或Java API,指定服务接口、实现类、版本号等信息,并通过`<dubbo:service>`标签将服务暴露出去。同时,服务提供者需要连接注册中心,例如Zookeeper,...
Java-Service-Provider:PiDev Java 是一个与Java平台服务提供者接口(SPI)相关的项目。SPI是Java标准库中的一个重要组成部分,它允许第三方开发者扩展Java应用程序或库的功能。在这个项目中,PiDev可能提供了创建、...
- **SMGP**(Short Message Gateway Protocol)是中国移动的短信网关协议,适用于SP(Service Provider)与短信中心之间的通信。 - **SGIP**(Simple Gateway Interworking Protocol)是中国电信的简单网关互操作...
3. **TCC服务提供者(TCC Service Provider)**:提供TCC模式下的业务服务实现,包括Try、Confirm和Cancel的具体逻辑。 4. **TCC服务消费者(TCC Service Consumer)**:调用TCC服务提供者的业务接口,触发分布式...