JDK中,基于SPI的思想,提供了默认具体的实现,ServiceLoader
。利用JDK自带的ServiceLoader
,可以轻松实现面向服务的注册与发现
,完成服务提供与使用的解耦
服务注册在META-INF/services文件夹下,通过serviceLoader发现META-INF下的服务。
由于应用面向接口编程,修改服务实现也不影响应用
从第三方包的META-INF/services/底下找类名,找到后初始化类,然后放入providers里
public class CustomServiceLoader {
public static final String MAPPING_CONFIG_PREFIX = "META-INF/services";
public static <S> List<S> loade(Class<S> service) throws Exception{
String mappingConfigFile = MAPPING_CONFIG_PREFIX + "/" + service.getName() ;
//由于一个接口的实现类可能存在多个jar包中的META-INF目录下,所以下面使用getResources返回一个URL数组
Enumeration<URL> configFileUrls = CustomServiceLoader.class.getClassLoader().getResources(mappingConfigFile);
if(configFileUrls == null){
return null ;
}
List<S> services = new LinkedList<S>();
while(configFileUrls.hasMoreElements()){
URL configFileUrl = configFileUrls.nextElement();
String configContent = IOUtils.toString(configFileUrl.openStream());
String[] serviceNames = configContent.split("\n");
for(String serviceName : serviceNames){
Class serviceClass = CustomServiceLoader.class.getClassLoader().loadClass(serviceName);
Object serviceInstance = serviceClass.newInstance();
services.add((S)serviceInstance);
}
}
return services ;
}
}
https://cxis.me/2017/04/17/Java%E4%B8%ADSPI%E6%9C%BA%E5%88%B6%E6%B7%B1%E5%85%A5%E5%8F%8A%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90/
https://juejin.im/post/5d2db85d6fb9a07ea7134408
https://blog.csdn.net/is_zhoufeng/article/details/50722440