Open
Description
Java
的SPI
是面向接口编程的典范,关于其意义和作用的分析,不是文本中重点,因此不做过多介绍,本文主要用于展示如何实际的构建并运行一个 demo.
项目模块结构
如上图所示,其中各个模块的作用分别如下:
spi-app
一个基于
Spring Boot
的Web
工程,用于使用SPI
提供的服务
spi-service
SPI
所提供的服务的接口,即定义
spi-service-provider-01
SPI
所提供的服务的一种具体实现
spi-service-provider-02
SPI
所提供的服务的另一种具体实现
服务的定义
首先是在spi-service
中,有一个接口ContentService
,提供一个内容,代码如下
package com.shellbye;
public interface ContentService {
public String getContent();
}
服务的使用
其次是在spi-app
中,对这个服务进行使用,首先需要添加依赖
<dependency>
<artifactId>spi-service</artifactId>
<groupId>spi-demo-group</groupId>
<version>1.0-SNAPSHOT</version>
</dependency>
然后是具体的示例代码
package com.example.demo;
import com.shellbye.ContentService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;
@RestController
public class Controller {
@GetMapping
public String main() {
System.out.println("enter");
List<ContentService> services = new ArrayList<>();
ServiceLoader<ContentService> loader = ServiceLoader.load(ContentService.class);
loader.forEach(contentProvider -> {
services.add(contentProvider);
System.out.println(contentProvider.getContent());
});
return "OK";
}
}
服务的实现
最后是服务的实现,由于两个实现基本一样,所以这里只展示一种。首先依然是需要添加依赖
<dependency>
<artifactId>spi-service</artifactId>
<groupId>spi-demo-group</groupId>
<version>1.0-SNAPSHOT</version>
</dependency>
然后是具体的实现代码
package com.shellbye;
public class HelloContentService implements ContentService {
@Override
public String getContent() {
return "Hello";
}
}
这里有一些需要特殊操作的地方,就是根据约定,需要在resources
中新建META-INF
,然后在其中新建services
,这个文件夹里需要以服务的接口的全限定名新建文件,文件里面的内容是具体的实现,比如文件名叫com.shellbye.ContentService
,里面具体的内容如下
com.shellbye.HiContentService
这样,一个具体的实现就搞定了,另一个也是一样的。
最后
光是有上面的配置其实还是不够的,虽然根据网上看到的一些资料似乎是可以的,但是实际运行的时候还需要在spi-app
添加对实现的依赖
<dependency>
<groupId>spi-demo-group</groupId>
<artifactId>spi-service-provider-01</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>spi-demo-group</groupId>
<artifactId>spi-service-provider-02</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
这个时候启动项目,在浏览器上访问 http://localhost:8080/
,就会在项目的控制台看到如下输出
enter
Hello
Hi
本项目涉及到的代码在这里。