ServiceLoader类:
使用过程:
public static void main(String[] args){
// 找到实现driver接口的数据库厂商的实现类
// ServiceLoader:此方法先由系统类加载器来尝试加载,由双亲委托模型,此方法尝试使用boot
// 加载器来加载,根加载器可以成功加载。如果不使用ServiceLoader.load,则尝试使用boot来加载
// Driver,而Driver在classpath路径下,不能由boot加载,加载失败
ServiceLoader<Driver> loader = ServiceLoader.load(Driver.class);
Iterator<Driver> iterator = loader.iterator();
//遵循SPI规范,去特定的目录寻找特定的文件然后解析出文件里的每一行,并且把每一行的信息读取出来,在
//需要的时候进行加载
while (iterator.hasNext()){
Driver driver = iterator.next();
System.out.println("driver: " + driver.getClass()
+ ", loader: " + driver.getClass().getClassLoader());
}
System.out.println("CurrentThreadClassLoader : " + Thread.currentThread().getContextClassLoader());
System.out.println("ServiceLoader的类加载器 :"+ ServiceLoader.class.getClassLoader());
}
方法解析:
public static <S> ServiceLoader<S> load(Class<S> service) {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
//使用上下文类加载器,当前线程的上下文加载器(系统加载器)来加载
return new ServiceLoader<>(Reflection.getCallerClass(), service, cl);
}
ServiceLoader方法:
private ServiceLoader(Class<?> caller, Class<S> svc, ClassLoader cl) {
Objects.requireNonNull(svc);
if (VM.isBooted()) {
checkCaller(caller, svc);
if (cl == null) {
cl = ClassLoader.getSystemClassLoader();
}
} else {
// if we get here then it means that ServiceLoader is being used
// before the VM initialization has completed. At this point then
// only code in the java.base should be executing.
Module callerModule = caller.getModule();
Module base = Object.class.getModule();
Module svcModule = svc.getModule();
if (callerModule != base || svcModule != base) {
fail(svc, "not accessible to " + callerModule + " during VM init");
}
// restricted to boot loader during startup
cl = null;
}
this.service = svc;
this.serviceName = svc.getName();
this.layer = null;
this.loader = cl; //全局加载器设置为C1
this.acc = (System.getSecurityManager() != null)
? AccessController.getContext()
: null;
}
下面方法中的forname方法特别关键:
/**
* Loads and returns the next provider class.
*/
private Class<?> nextProviderClass() {
if (configs == null) {
try {
String fullName = PREFIX + service.getName();
if (loader == null) {
configs = ClassLoader.getSystemResources(fullName);
} else if (loader == ClassLoaders.platformClassLoader()) {
// The platform classloader doesn't have a class path,
// but the boot loader might.
if (BootLoader.hasClassPath()) {
configs = BootLoader.findResources(fullName);
} else {
configs = Collections.emptyEnumeration();
}
} else {
configs = loader.getResources(fullName);
}
} catch (IOException x) {
fail(service, "Error locating configuration files", x);
}
}
while ((pending == null) || !pending.hasNext()) {
if (!configs.hasMoreElements()) {
return null;
}
pending = parse(configs.nextElement());
}
String cn = pending.next();
try {
return Class.forName(cn, false, loader);
//关键,loader为系统加载器(由上下文加载器设置出来的)
} catch (ClassNotFoundException x) {
fail(service, "Provider " + cn + " not found");
return null;
}
}
public static Class<?> forName(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException
{
Class<?> caller = null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// Reflective call to get caller class is only needed if a security manager
// is present. Avoid the overhead of making this call otherwise.
caller = Reflection.getCallerClass();
if (loader == null) {
ClassLoader ccl = ClassLoader.getClassLoader(caller);
if (ccl != null) {
sm.checkPermission(
SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
}
return forName0(name, initialize, loader, caller);
}