归档
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 ; } }