关于JAVA SPI详细的介绍请看:JAVA - SPI机制使用详解(一)
主要角色有:接口、多个实现类以及测试客户端,在每个实现类中需要创建信息文件:resources/META-INF/services/接口全限定名一致的文件。接口、多个实现类以及客户端分别在不同的MODULE中。
①. 接口:
package com.hadoopx.javax.spi;
public interface Coder {
public String write();
}
②. 第一个实现类:
package com.hadoopx.javax.spi;
public class Javaer implements Coder {
public String write() {
return "I'M JAVA CODER, USE JAVA TO WRITE EVERYTHING.";
}
}
创建信息说明文件:resources/META-INF/services/com.hadoopx.javax.spi.Coder,
里面的内容为:com.hadoopx.javax.spi.Javaer
③. 第二个实现类:
package com.hadoopx.javax.spi;
public class Rubyer implements Coder {
public String write() {
return "I'M RUBY CODER, USE RUBY TO WRITE EVERYTHING.";
}
}
创建信息说明文件:resources/META-INF/services/com.hadoopx.javax.spi.Coder,
里面的内容为:com.hadoopx.javax.spi.Rubyer
④. 客户端:
添加依赖:
<dependencies>
<dependency>
<groupId>com.hadoopx</groupId>
<artifactId>javax-spi001-javaer</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.hadoopx</groupId>
<artifactId>javax-spi001-rubyer</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
客户端代码:
package com.hadoopx.javax.spi;
public class MyTest {
public static void main(String[] args) {
ServiceLoader<Coder> s = ServiceLoader.load(Coder.class);
Iterator<Coder> iterator = s.iterator();
while (iterator.hasNext()) {
Coder lang = iterator.next();
String content = lang.write();
System.out.println(content);
}
}
}
输出结果为:
I'M JAVA CODER, USE JAVA TO WRITE EVERYTHING.
I'M RUBY CODER, USE RUBY TO WRITE EVERYTHING.
在实际的使用过程中,需要指定不同的类型来创建不同的实现类实例。
注意: 在每个实现类中不需要创建信息文件。
①. 接口:
package com.hadoopx.javax.spi;
public interface Coder {
public String write();
}
②. 第一个实现类:
package com.hadoopx.javax.spi;
@Service
@Primary
public class Javaer implements Coder {
public String write() {
return "I'M JAVA CODER, USE JAVA TO WRITE EVERYTHING.";
}
}
③. 第二个实现类:
package com.hadoopx.javax.spi;
@Service
public class Rubyer implements Coder {
public String write() {
return "I'M RUBY CODER, USE RUBY TO WRITE EVERYTHING.";
}
}
④. 客户端一:
添加依赖:
<dependencies>
<dependency>
<groupId>com.hadoopx</groupId>
<artifactId>javax-spi002-javaer</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.hadoopx</groupId>
<artifactId>javax-spi002-rubyer</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
客户端代码:
@RestController
@RequestMapping("/t")
@Api(value = "测试服务", description = "该服务仅仅用于完成验证、学习和测试")
public class TestController {
// 切换不同的服务
@Autowired
@Qualifier("javaer")
private Coder coder;
@ApiOperation(value = "测试", notes = "基于SPRING BOOT实现的JAVA SPI机制的DEMO")
@GetMapping("/spi")
public String test() {
System.out.println(coder.write());
return "ok";
}
}
输出结果为:
I'M JAVA CODER, USE JAVA TO WRITE EVERYTHING.
⑤. 客户端二:
有时会根据不同的情况,调用不同服务的方法,所以在客户端中需要多增加下面这个文件:
@Service
public class CoderContext {
// 通过 @Autowired 把Coder所有的实现类注入到map(coders)中.
// Spring会查找应用的上下文里类型为Coder的Bean, 并把查找到的Bean注入到Map 或者 List中
@Autowired
Map<String, Coder> coders;
public Coder getCoder(String key){
return coders.get(key);
}
}
客户端代码:
@RestController
@RequestMapping("/t")
@Api(value = "测试服务", description = "该服务仅仅用于完成验证、学习和测试")
public class TestController {
@Autowired
private CoderContext coderContext;
@ApiOperation(value = "测试", notes = "基于SPRING BOOT实现的JAVA SPI机制的DEMO")
@GetMapping("/spi")
public String test(String type) {
System.out.println(coderContext.getCoder(type).write());
return "ok";
}
}