归档
SPI 源码说明
public final class ServiceLoader < S > implements Iterable < S > {
public static < S > ServiceLoader < S > load ( Class < S > service, ClassLoader loader) {
return new ServiceLoader < > ( service, loader) ;
}
private ServiceLoader ( Class < S > svc, ClassLoader cl) {
service = Objects . requireNonNull ( svc, "Service interface cannot be null" ) ;
loader = ( cl == null ) ? ClassLoader . getSystemClassLoader ( ) : cl;
. . .
reload ( ) ;
}
public void reload ( ) {
providers. clear ( ) ;
lookupIterator = new LazyIterator ( service, loader) ;
}
@Override
public Iterator < S > iterator ( ) {
return new Iterator < S > ( ) {
Iterator < Map. Entry < String , S > > knownProviders = providers. entrySet ( ) . iterator ( ) ;
. . .
public S next ( ) {
if ( knownProviders. hasNext ( ) )
return knownProviders. next ( ) . getValue ( ) ;
return lookupIterator. next ( ) ;
}
. . .
} ;
}
}
java.util.ServiceLoader.LazyIterator
private class LazyIterator implements Iterator < S > {
private LazyIterator ( Class < S > service, ClassLoader loader) {
this . service = service;
this . loader = loader;
}
public S next ( ) {
if ( acc == null ) {
return nextService ( ) ;
}
. . .
}
private S nextService ( ) {
. . .
String cn = nextName;
Class < ? > c = null ;
try {
c = Class . forName ( cn, false , loader) ;
} catch ( ClassNotFoundException x) {
. . .
}
. . .
try {
S p = service. cast ( c. newInstance ( ) ) ;
providers. put ( cn, p) ;
return p;
}
. . .
}
private boolean hasNextService ( ) {
. . .
if ( configs == null ) {
try {
String fullName = PREFIX + service. getName ( ) ;
. . .
configs = loader. getResources ( fullName) ;
}
. . .
}
while ( ( pending == null ) || ! pending. hasNext ( ) ) {
if ( ! configs. hasMoreElements ( ) ) {
return false ;
}
pending = parse ( service, configs. nextElement ( ) ) ;
}
nextName = pending. next ( ) ;
return true ;
}
}