Java SPI (Service Provider Interface) 是一种标准的服务发现机制,它允许 java 应用程序在运行时扩展第三方库的功能。
接口 Service
package com;
public interface Service {
Double calculate(Double a,Double b);
}
2个实现类(该工程依赖于接口所在的工程)
package com.wsd;
import com.Service;
public class ServiceImpl01 implements Service {
@Override
public Double calculate(Double a,Double b) {
return a + b;
}
}
package com.wsd;
import com.Service;
public class ServiceImpl02 implements Service {
@Override
public Double calculate(Double a,Double b) {
return a * b;
}
}
main(该工程依赖于接口和实现类所在的2个工程)
package com.example.demo10;
import com.Service;
import java.io.InputStream;
import java.util.ServiceLoader;
public class Demo {
public static void main(String[] args) throws Exception {
// 使用 ServiceLoader 加载服务实现类
ServiceLoader<Service> serviceLoader = ServiceLoader.load(Service.class);
for(Service service : serviceLoader ){
System.out.println( service.calculate(2.0,3.0) );
}
}
}
ServiceLoader.load(Service.class); 参数 为接口,返回一个可迭代对象 其中包含了接口的2种实现类的对象 实现类的类名写在配置文件中,ServiceLoader.load 获取类名,加载所需的类,创建类的对象,将对象转型为Service.class(来自方法参数传的 接口类型)
配置文件的路径约定为 META-INF/services/ 接口完整类名
此处为 META-INF/services/com.service
运行结果:
自定义
package com.example.demo10;
import com.Service;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class Demo {
public static void main(String[] args) throws Exception {
/**
* Thread.currentThread() 获取当前的线程
* Thread.currentThread().getContextClassLoader() 获取当前线程的上下文类加载器
* Thread.currentThread().getContextClassLoader().getResource("application.properties");
* 获取类路径下的文件的输入流
*/
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("application.properties");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
List<String> classNames = new ArrayList<>();
String line;
//读取配置文件中的一行 获取类名
while ((line = reader.readLine()) != null) {
classNames.add(line);
}
for (String className : classNames) {
//根据类名 加载对应的类
Class<?> clazz = Class.forName(className);
//创建类的对象
Service service = (Service) clazz.newInstance();
System.out.println(service.calculate(2.0,3.0));
}
}
}
配置文件 application.properties
com.wsd.ServiceImpl01
com.wsd.ServiceImpl02
运行结果: