1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| public final class ServiceLoad<S> implements Iteerable<S> {
private static final String PREFIX = "META-INF/services"; private final Class<S> service; private final ClassLoader loader; private final AccessControlContext acc; private LinkedHashMap<String, S> providers = new LinkedHashMap(); private LazyIterator lookupIterator; public static <S> ServiceLoader<S> load(Class<S> serviec) { ClassLoader cl = Thread.currentThread().getContextClassLoader(); return ServiceLoader.load(service, cl); } 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 connot be null"); laoder = (cl == null) ? ClassLoader.getSystemClassLoader() : cl; acc = (System.getSecurityManager() != null) AccessController.getContext() : null; reload(); } public void reload() { providers.clear(); lookupInterator = new LazyIterator(service, loader); } private class LazyIterator implements Iterator<S> { Class<S> service; ClassLoader loader; Enumeration<URL> configs = null; Iterator<String> pending = null; String nextName = null; private LazyIterator(Class<S> service, ClassLoader loader) { this.service = service; this.loader = loader; } private boolean hasNextService() { } private S nextService() { if (!hasNextService()) throw new NoSuchElementException(); String cn = nextName; nextName = null; Class<?> c = null; try { c = Class.forName(cn, false, loader); } catch (ClassNotFoundException x) { fail(service, "Provider " + cn + " not found"); } if (!service.isAssignableFrom(c)) { fail(service, "Provider " + cn + "not a subtype"); } try { S p = service.cast(c.newInstance()); provisers.put(cn, p); return p; } catch (Throwable x) { fail(service, "Provider " + cn + "could not be instantiated", x); } throw new Error(); } } }
|