一。前言
在面向的对象的设计里,一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改源代码,然后重新编译、发布。
为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。java spi就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似spring IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。
很多开源项目都使用这种机制。
java spi的具体约定为:
当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。基于这样一个约定就能很好的找到服务接口的实现类,而不需要再代码里制定。
java.sql.Driver就是这么实现的,我们可以看看mysql是如何扩展它的。
打开mysql的jdbc jar包,在META-INF/services下有一个java.sql.Drvier的文件,
文件内容如下:
二。实例开发
在代码中,如何使用java的spi机制,这时就要借助java.util.ServiceLoader了。
开发步骤如下:
1、编写一个接口
2、编写接口的实现类
3、在/src/META-INF/services下新建一个文件,文件名为接口的包名+接口名,如果是maven构建,就在src/main/resources/META-INF/services
4、把实现类的全名写在该文件中,一个实现类占一行。
package com.wxj.spi;
/**
* 保存接口
* @author wxj
*
*/
public interface Store
{
/**
* 保存数据
* @param data 数据
* @return 是否保存成功
*/
public boolean store(Object data);
}
package com.wxj.spi;
/**
* 用文件保存数据
* @author wxj
*
*/
public class FileStore implements Store
{
@Override
public boolean store(Object data)
{
System.out.println("file store successfully");
return true;
}
}
package com.wxj.spi;
/**
* 用数据库保存数据
* @author wxj
*
*/
public class DBStore implements Store
{
@Override
public boolean store(Object data)
{
System.out.println("db store successfully");
return true;
}
}
src/META-INF/services/com.wxj.spi.Store的文件内容:
com.wxj.spi.FileStore
com.wxj.spi.DBStore
测试类
package com.wxj.spi;
import java.util.Iterator;
import java.util.ServiceLoader;
/**
* 测试类
* @author wxj
*
*/
public class TestStore
{
public static void main(String[] args)
{
ServiceLoader<Store> stores = ServiceLoader.load(Store.class);
Iterator<Store> it = stores.iterator();
Store s = null;
String data = "datas";
while(it.hasNext())
{
s = it.next();
s.store(data);
}
}
}
相关推荐
9. **协议(Protocol)或合同(Contract)**:在某些语言中,如C#的接口或Java的SPI(Service Provider Interface),模块间的通信可以通过事先定义的协议或合同来规范,确保模块间的数据交换符合约定。 在提供的...
在Android应用中,各个功能模块可以通过定义接口,将实现细节封装在单独的组件中,降低模块间的耦合度。 2. **插件化加载**:Android应用可以利用类加载器(ClassLoader)的特性,动态加载实现指定接口的类。这样,...
这种高度可插拔的架构使得Dubbo能够适应各种复杂场景,同时降低了模块间的耦合度。 在实际应用中,理解并掌握Dubbo SPI的工作原理和使用方法,可以帮助我们更好地利用Dubbo进行服务的开发和维护。例如,当我们需要...
SPI(Service Provider Interface)是Java平台提供的一种服务发现与加载机制,它允许应用程序在运行时动态地查找并加载实现特定接口的服务。这个概念是Java生态系统中的一个重要组成部分,它为组件化开发提供了强大...
在设计原理部分,本书会深入讨论Spring的模块化设计,以及如何利用IoC容器、AOP等核心概念来实现松耦合和高内聚的系统。此外,还会探讨Spring如何通过扩展点和SPI(Service Provider Interface)来支持定制化开发。 ...
在Java世界中,依赖注入是一种设计模式,通过将依赖关系从代码中分离出来,实现对象的组装,降低了组件间的耦合度。 **架构** CDI架构包含以下几个关键部分: 1. **合约**:CDI定义了一套标准的API和SPI(Service ...
在现代微服务架构中,dubbox-dubbox-2.8.4a能够帮助开发者构建松耦合、可独立部署的服务,提升系统的可维护性和扩展性。源码解读有助于理解和应用微服务的最佳实践。 通过深入研究dubbox-dubbox-2.8.4a的源码,...
- 微核+插件体系:Dubbo采用微内核架构,核心功能精简,通过插件化设计实现功能扩展,如协议、序列化、注册中心等,这样既保证了核心的稳定,又允许灵活添加新的功能。 - 平等对待第三方:Dubbo支持各种第三方组件...
7. **SPI扩展机制**:dubbo采用Java的Service Provider Interface(SPI)机制,方便用户自定义实现各种接口,实现功能扩展。 在【压缩包子文件的文件名称列表】"apache-dubbo-3.1.4-src"中,你可以找到dubbo的主要...
2. **插件架构**:有几种常见的插件架构,如“动态链接库”(DLL)模式、Java的“服务提供者接口”(SPI)和“模块化插件系统”如OSGi。这些架构允许在不修改主程序的情况下添加、更新或移除插件。 3. **优点**:插件...
- **设计流程**:包括需求分析、系统架构设计、软硬件模块划分、实现与测试等阶段。 #### 三、ARM7体系结构 - **特点**:ARM7采用了RISC(精简指令集)架构,具有低功耗、高性能的特点,适合嵌入式系统应用。 - *...
1. **模块系统**:OSGI基于JAR文件作为模块的基本单位,每个模块都有自己的类路径和导出/导入包规则,实现了模块间的隔离。 2. **生命周期管理**:OSGI环境中,模块有启动、运行、暂停、停止和卸载等生命周期状态,...
**CREATEASY Spring整合详解** CREATEASY 是一个轻量级的框架,它主要为Java应用程序提供了RESTful服务的支持。...这种集成方式在微服务架构中尤其常见,因为它允许各个服务之间通过HTTP进行通信,实现松耦合。
它通过接口定义服务,实现了服务的松耦合,使开发者可以专注于业务逻辑,而无需关心底层实现细节。 二、服务注册与发现 在Dubbo中,服务提供者(Provider)启动时会将服务注册到注册中心(如Zookeeper),服务消费...
Dubbo是阿里巴巴开源的一款高性能、轻量级的Java服务治理框架,广泛应用于微服务架构中。 **整体设计** Dubbo的核心设计围绕着服务的暴露和引用,其主要组成部分包括:服务接口、服务提供者、服务消费者、注册中心...
在IT行业中,Spring框架是Java开发领域中的一个关键组件,尤其在企业级应用开发中扮演着核心角色。这个"Spring实践教程"似乎旨在帮助开发者深入理解和应用Spring框架。以下是关于Spring框架的一些详细知识点: 1. *...
在Java中,插件系统通常依赖于服务定位器和服务提供者接口(SPI)来实现组件之间的松耦合。BriarCraftPlugin可能利用了Java的反射机制和接口来加载和管理插件。开发者可以通过编写符合特定接口的类,实现自定义功能...