JAVA拾遗关于SPI机制

编程

原文:https://www.cnkirito.moe/spi/

一、实现一个自定义的SPI

1.项目结构

  • invoker是用来测试的主项目
  • interface是针对厂商和插件商定义的接口项目,只提供接口,不提供实现
  • good-printer,bad-printer分别是两个厂商对interface的不同实现,所以他们会依赖于interface项目

主要实现的是,在不改变invoker代码,只更改依赖的前提下,切换interface的实现厂商

2.interface模块

com.spi.Printer

public interface Printer {

void print();

}

interface只定义一个接口,不提供实现。规范的制定方一般都是比较牛叉的存在,这些接口通常位于java,javax前缀的包中,这里的printer只是模拟的一个规范接口。

3.good-printer模块

3.1 good-printerpom.xml

<dependencies>

<dependency>

<groupId>com.lara</groupId>

<artifactId>interface</artifactId>

<version>1.0-SNAPSHOT</version>

</dependency>

</dependencies>

规范的具体实现类必然要依赖规范接口

3.2 com.spi.GoodPrinter

public class GoodPrinter implements Printer {

public void print() {

System.out.println("you are good");

}

}

作为printer规范接口的实现一

3.3 在resource下添加services文件

每一个SPI接口都需要在自己项目的静态资源目录中声明一个services文件,文件名为实现规范接口的类名全路径,此例中便是 com.spi.Printer,文件中的内同则为实现类的全路径,此例中便是com.spi.GoodPrinter.

这样一个厂商的实现便完成了。

4.bad-printer模块

和上述的good-printer的实现一样

4.1 bad-printerpom.xml

<dependencies>

<dependency>

<groupId>com.lara</groupId>

<artifactId>interface</artifactId>

<version>1.0-SNAPSHOT</version>

</dependency>

</dependencies>

4.2com.spi.BadPrinter

public class BadPrinter implements Printer {

public void print() {

System.out.println("you are bad");

}

}

4.3在resource下添加services文件

5.invoker模块

这里的invoker便是我们自己的项目了。如果一开始我们想使用厂商bad-printer的Printer实现,是需要将其的依赖引入

<dependencies>

<dependency>

<groupId>com.lara</groupId>

<artifactId>interface</artifactId>

<version>1.0-SNAPSHOT</version>

</dependency>

<dependency>

<groupId>com.lara</groupId>

<artifactId>bad-printer</artifactId>

<version>1.0-SNAPSHOT</version>

</dependency>

</dependencies>

5.1编写调用主类

public class MainClass {

public static void main(String[] args) {

ServiceLoader<Printer> printLoaders = ServiceLoader.load(Printer.class);

for (Printer printer : printLoaders){

printer.print();

}

}

}

ServiceLoader是java.util提个的用于加载固定类路径下文件的一个加载器,正式它加载了对应接口声明的实现类。

5.2打印结果1

在后续的方案中,想替换厂商的Printer实现,只需要将依赖更换,调用主类无需变更代码,符合开闭原则。

5.3打印结果2

以上是 JAVA拾遗关于SPI机制 的全部内容, 来源链接: utcz.com/z/517854.html

回到顶部