ServiceLoader
ServiceLoader核心代码
ServiceLoader.load(clazz, SPIExtensionLoader.class.getClassLoader()).iterator();
private static <T> List<T> findExtensions(Class<T> clazz) {
List<T> list = new ArrayList<>();
Iterator<T> iterator = ServiceLoader.load(clazz, SPIExtensionLoader.class.getClassLoader()).iterator();
while (iterator.hasNext()) {
list.add(iterator.next());
}
return list;
}
配置/resources/META-INF/services/
一个完整的例子
java接口类
public interface ConfigService {
public String getConfigParam();
}
加载接口实现类的逻辑
Main方法入口
public static void main(String[] args) {
ConfigService configService = SPIExtensionLoader.loadExtension(ConfigService.class);
System.out.println(configService.getConfigParam());
}
SPIExtensionLoader.java
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
public class SPIExtensionLoader {
public static <T> T loadExtension(Class<T> clazz) {
List<T> extensions = findExtensions(clazz);
if (extensions != null && extensions.size() > 0) {
if (extensions.size() > 1) {
throw new IllegalArgumentException(String.format("There is multiple implemention of :%s", clazz.getName()));
} else {
return extensions.get(0);
}
} else {
throw new IllegalArgumentException(String.format("There is no implemention of :%s", clazz.getName()));
}
}
private static <T> List<T> findExtensions(Class<T> clazz) {
List<T> list = new ArrayList<>();
Iterator<T> iterator = ServiceLoader.load(clazz, SPIExtensionLoader.class.getClassLoader()).iterator();
while (iterator.hasNext()) {
list.add(iterator.next());
}
return list;
}
}
impl接口实现类
public class ConfigServiceZkImpl implements ConfigService {
@Override
public String getConfigParam() {
return "zkconfig";
}
}
实现类的配置
resources\META-INF\services\com.qbsea.loader.service.ConfigService
里面的具体内容为
com.qbsea.loader.service.impl.ConfigServiceZkImpl
即如图为