今天得空看了一下ServiceLoader的源码,以前只是会使用这么个东西,但是不清楚里边的来龙去脉的,看完代码之后还是有点小收获的,嘻嘻,所以记录了下来。
ServiceLoad是jdk1.6才加的这么一个类,一个简单的服务提供者加载设施
下面就带着疑问来看代码
Q1.为什么ServiceLoader可以遍历呢?
Q2.为什么在resources/META-INF/services下的文件是全路径呢?
Q3.为什么一定要放在META-INF/services这个路径下呢?
A1:ServiceLoader实现了Iterate的接口
public final class ServiceLoader<S>
implements Iterable<S>
A2:通过反射的方式获取到文件名
Class<?> c = null;
try {
c = Class.forName(cn, false, loader);
} catch (ClassNotFoundException x) {
fail(service,
// Android-changed: Let the ServiceConfigurationError have a cause.
"Provider " + cn + " not found", x);
// "Provider " + cn + " not found");
}
A3:用代码说话,打开ServiceLoader的代码可以看到有个PREFIX的常量
private static final String PREFIX = "META-INF/services/";
private boolean hasNextService() {
if (nextName != null) {
return true;
}
if (configs == null) {
try {
String fullName = PREFIX + service.getName();
if (loader == null)
configs = ClassLoader.getSystemResources(fullName);
else
configs = loader.getResources(fullName);
} catch (IOException x) {
fail(service, "Error locating configuration files", x);
}
}
while ((pending == null) || !pending.hasNext()) {
if (!configs.hasMoreElements()) {
return false;
}
pending = parse(service, configs.nextElement());
}
nextName = pending.next();
return true;
}