diff options
author | Elliott Hughes <enh@google.com> | 2010-04-06 16:36:51 -0700 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2010-04-06 16:36:51 -0700 |
commit | 64e526d079a7218f984eeaba6ff2feeaadeeaffb (patch) | |
tree | f52c323d8aec61cebddaf7485900dff5edede194 /luni | |
parent | 75107682f111073add772464a4ed9e9c1bc9bd77 (diff) | |
download | libcore-64e526d079a7218f984eeaba6ff2feeaadeeaffb.zip libcore-64e526d079a7218f984eeaba6ff2feeaadeeaffb.tar.gz libcore-64e526d079a7218f984eeaba6ff2feeaadeeaffb.tar.bz2 |
Actually use ServiceLoader in places where we had a hard-coded equivalent.
I've also removed a file that was causing us to use this code unnecessarily
at run-time to explicitly specify the built-in default PreferencesFactory.
I haven't touched Charset, but should come back and fix that too at some
point.
Change-Id: I3a2145041d048078bdb55ae7b8fa4ec9d8726922
Diffstat (limited to 'luni')
-rw-r--r-- | luni/src/main/java/java/util/ServiceLoader.java | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/luni/src/main/java/java/util/ServiceLoader.java b/luni/src/main/java/java/util/ServiceLoader.java index 2f28dff..335a1db 100644 --- a/luni/src/main/java/java/util/ServiceLoader.java +++ b/luni/src/main/java/java/util/ServiceLoader.java @@ -62,6 +62,8 @@ import java.net.URL; * * <p>Note that each iteration creates new instances of the various service implementations, so * any heavily-used code will likely want to cache the known implementations itself and reuse them. + * Note also that the candidate classes are instantiated lazily as you call {@code next} on the + * iterator: construction of the iterator itself does not instantiate any of the providers. * * @param <S> the service class or interface * @since 1.6 @@ -106,13 +108,17 @@ public final class ServiceLoader<S> implements Iterable<S> { } /** - * Constructs a service loader. + * Constructs a service loader. If {@code classLoader} is null, the system class loader + * is used. * * @param service the service class or interface - * @param loader the class loader + * @param classLoader the class loader * @return a new ServiceLoader */ public static <S> ServiceLoader<S> load(Class<S> service, ClassLoader classLoader) { + if (classLoader == null) { + classLoader = ClassLoader.getSystemClassLoader(); + } return new ServiceLoader<S>(service, classLoader); } @@ -120,16 +126,12 @@ public final class ServiceLoader<S> implements Iterable<S> { services.clear(); try { String name = "META-INF/services/" + service.getName(); - services.addAll(Collections.list(classLoader().getResources(name))); + services.addAll(Collections.list(classLoader.getResources(name))); } catch (IOException e) { return; } } - private ClassLoader classLoader() { - return (classLoader != null) ? classLoader : ClassLoader.getSystemClassLoader(); - } - /** * Constructs a service loader, using the current thread's context class loader. * @@ -156,6 +158,29 @@ public final class ServiceLoader<S> implements Iterable<S> { return ServiceLoader.load(service, cl); } + /** + * Internal API to support built-in SPIs that check a system property first. + * Returns an instance specified by a property with the class' binary name, or null if + * no such property is set. + * @hide + */ + public static <S> S loadFromSystemProperty(final Class<S> service) { + return AccessController.doPrivileged(new PrivilegedAction<S>() { + public S run() { + try { + final String className = System.getProperty(service.getName()); + if (className != null) { + Class<?> c = ClassLoader.getSystemClassLoader().loadClass(className); + return (S) c.newInstance(); + } + return null; + } catch (Exception e) { + throw new Error(e); + } + } + }); + } + @Override public String toString() { return "ServiceLoader for " + service.getName(); @@ -190,11 +215,7 @@ public final class ServiceLoader<S> implements Iterable<S> { } String className = queue.remove(); try { - if (classLoader == null) { - return service.cast(Class.forName(className).newInstance()); - } else { - return service.cast(classLoader.loadClass(className).newInstance()); - } + return service.cast(classLoader.loadClass(className).newInstance()); } catch (Exception e) { throw new ServiceConfigurationError("Couldn't instantiate class " + className, e); } |