ServiceLoader Class
Definition
Important
Some information relates to prerelease product that may be substantially modified before it’s released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
A facility to load implementations of a service.
[Android.Runtime.Register("java/util/ServiceLoader", DoNotGenerateAcw=true)]
[Java.Interop.JavaTypeParameters(new System.String[] { "S" })]
public sealed class ServiceLoader : Java.Lang.Object, IDisposable, Java.Interop.IJavaPeerable, Java.Lang.IIterable
[<Android.Runtime.Register("java/util/ServiceLoader", DoNotGenerateAcw=true)>]
[<Java.Interop.JavaTypeParameters(new System.String[] { "S" })>]
type ServiceLoader = class
inherit Object
interface IIterable
interface IJavaObject
interface IDisposable
interface IJavaPeerable
- Inheritance
- Attributes
- Implements
Remarks
A facility to load implementations of a service.
A service is a well-known interface or class for which zero, one, or many service providers exist. A service provider (or just provider) is a class that implements or subclasses the well-known interface or class. A ServiceLoader
is an object that locates and loads service providers deployed in the run time environment at a time of an application's choosing. Application code refers only to the service, not to service providers, and is assumed to be capable of choosing between multiple service providers (based on the functionality they expose through the service), and handling the possibility that no service providers are located.
<h2> Obtaining a service loader </h2>
An application obtains a service loader for a given service by invoking one of the static load
methods of ServiceLoader
. <!--If the application is a module, then its module declaration must have a uses directive that specifies the service; this helps to locate providers and ensure they will execute reliably. In addition, if the application module does not contain the service, then its module declaration must have a requires directive that specifies the module which exports the service. It is strongly recommended that the application module does <b>not</b> require modules which contain providers of the service.--/>
A service loader can be used to locate and instantiate providers of the service by means of the #iterator() iterator
method. ServiceLoader
also defines the #stream() stream
method to obtain a stream of providers that can be inspected and filtered without instantiating them.
As an example, suppose the service is com.example.CodecFactory
, an interface that defines methods for producing encoders and decoders:
{@code
package com.example;
public interface CodecFactory {
Encoder getEncoder(String encodingName);
Decoder getDecoder(String encodingName);
}
}
The following code obtains a service loader for the CodecFactory
service, then uses its iterator (created automatically by the enhanced-for loop) to yield instances of the service providers that are located:
{@code
ServiceLoader<CodecFactory> loader = ServiceLoader.load(CodecFactory.class);
for (CodecFactory factory : loader) {
Encoder enc = factory.getEncoder("PNG");
if (enc != null)
... use enc to encode a PNG file
break;
}
}
Sometimes an application may wish to inspect a service provider before instantiating it, in order to determine if an instance of that service provider would be useful. For example, a service provider for CodecFactory
that is capable of producing a "PNG" encoder may be annotated with @PNG
. The following code uses service loader's stream
method to yield instances of Provider<CodecFactory>
in contrast to how the iterator yields instances of CodecFactory
:
{@code
ServiceLoader<CodecFactory> loader = ServiceLoader.load(CodecFactory.class);
Set<CodecFactory> pngFactories = loader
.stream() // Note a below
.filter(p -> p.type().isAnnotationPresent(PNG.class)) // Note b
.map(Provider::get) // Note c
.collect(Collectors.toSet());
}
<ol type="a"> <li> A stream of Provider<CodecFactory>
objects </li> <li> p.type()
yields a Class<CodecFactory>
</li> <li> get()
yields an instance of CodecFactory
</li> </ol>
<h2> Designing services </h2>
A service is a single type, usually an interface or abstract class. A concrete class can be used, but this is not recommended. The type may have any accessibility. The methods of a service are highly domain-specific, so this API specification cannot give concrete advice about their form or function. However, there are two general guidelines: <ol> <li>
A service should declare as many methods as needed to allow service providers to communicate their domain-specific properties and other quality-of-implementation factors. An application which obtains a service loader for the service may then invoke these methods on each instance of a service provider, in order to choose the best provider for the application.
</li> <li>
A service should express whether its service providers are intended to be direct implementations of the service or to be an indirection mechanism such as a "proxy" or a "factory". Service providers tend to be indirection mechanisms when domain-specific objects are relatively expensive to instantiate; in this case, the service should be designed so that service providers are abstractions which create the "real" implementation on demand. For example, the CodecFactory
service expresses through its name that its service providers are factories for codecs, rather than codecs themselves, because it may be expensive or complicated to produce certain codecs.
</li> </ol>
<h2> "developing-service-providers">Developing service providers</h2>
A service provider is a single type, usually a concrete class. An interface or abstract class is permitted because it may declare a static provider method, discussed later. The type must be public and must not be an inner class.
A service provider and its supporting code may be developed in a module, which is then deployed on the application module path or in a modular image. Alternatively, a service provider and its supporting code may be packaged as a JAR file and deployed on the application class path. The advantage of developing a service provider in a module is that the provider can be fully encapsulated to hide all details of its implementation.
An application that obtains a service loader for a given service is indifferent to whether providers of the service are deployed in modules or packaged as JAR files. The application instantiates service providers via the service loader's iterator, or via Provider Provider
objects in the service loader's stream, without knowledge of the service providers' locations.
<h2> Deploying service providers on the class path </h2>
A service provider that is packaged as a JAR file for the class path is identified by placing a provider-configuration file in the resource directory META-INF/services
. The name of the provider-configuration file is the fully qualified binary name of the service. The provider-configuration file contains a list of fully qualified binary names of service providers, one per line.
For example, suppose the service provider com.example.impl.StandardCodecs
is packaged in a JAR file for the class path. The JAR file will contain a provider-configuration file named:
<blockquote>META-INF/services/com.example.CodecFactory
</blockquote>
that contains the line:
<blockquote>com.example.impl.StandardCodecs # Standard codecs
</blockquote>
"format">The provider-configuration file must be encoded in UTF-8. Space and tab characters surrounding each service provider's name, as well as blank lines, are ignored. The comment character is '#'
(U+0023
<span style="font-size:smaller;">NUMBER SIGN</span>); on each line all characters following the first comment character are ignored. If a service provider class name is listed more than once in a provider-configuration file then the duplicate is ignored. If a service provider class is named in more than one configuration file then the duplicate is ignored.
A service provider that is mentioned in a provider-configuration file may be located in the same JAR file as the provider-configuration file or in a different JAR file. The service provider must be visible from the class loader that is initially queried to locate the provider-configuration file; this is not necessarily the class loader which ultimately locates the provider-configuration file.
<h2> Timing of provider discovery </h2>
Service providers are loaded and instantiated lazily, that is, on demand. A service loader maintains a cache of the providers that have been loaded so far. Each invocation of the iterator
method returns an Iterator
that first yields all of the elements cached from previous iteration, in instantiation order, and then lazily locates and instantiates any remaining providers, adding each one to the cache in turn. Similarly, each invocation of the stream method returns a Stream
that first processes all providers loaded by previous stream operations, in load order, and then lazily locates any remaining providers. Caches are cleared via the #reload reload
method.
<h2> "errors">Errors</h2>
When using the service loader's iterator
, the Iterator#hasNext() hasNext
and Iterator#next() next
methods will fail with ServiceConfigurationError
if an error occurs locating, loading or instantiating a service provider. When processing the service loader's stream then ServiceConfigurationError
may be thrown by any method that causes a service provider to be located or loaded.
When loading or instantiating a service provider in a module, ServiceConfigurationError
can be thrown for the following reasons:
When reading a provider-configuration file, or loading or instantiating a provider class named in a provider-configuration file, then ServiceConfigurationError
can be thrown for the following reasons:
<ul>
<li> The format of the provider-configuration file violates the format specified above; </li>
<li> An IOException IOException
occurs while reading the provider-configuration file; </li>
<li> A service provider cannot be loaded; </li>
<li> A service provider is not assignable to the service's interface or class, or does not define a provider constructor, or cannot be instantiated. </li>
</ul>
<h2> Concurrency </h2>
Instances of this class are not safe for use by multiple concurrent threads.
<h3> Null handling </h3>
Unless otherwise specified, passing a null
argument to any method in this class will cause a NullPointerException
to be thrown.
Added in 1.6.
Java documentation for java.util.ServiceLoader
.
Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.
Properties
Class |
Returns the runtime class of this |
Handle |
The handle to the underlying Android instance. (Inherited from Object) |
JniIdentityHashCode | (Inherited from Object) |
JniPeerMembers | |
PeerReference | (Inherited from Object) |
ThresholdClass |
This API supports the Mono for Android infrastructure and is not intended to be used directly from your code. (Inherited from Object) |
ThresholdType |
This API supports the Mono for Android infrastructure and is not intended to be used directly from your code. (Inherited from Object) |
Methods
Clone() |
Creates and returns a copy of this object. (Inherited from Object) |
Dispose() | (Inherited from Object) |
Dispose(Boolean) | (Inherited from Object) |
Equals(Object) |
Indicates whether some other object is "equal to" this one. (Inherited from Object) |
FindFirst() |
Load the first available service provider of this loader's service. |
GetHashCode() |
Returns a hash code value for the object. (Inherited from Object) |
Iterator() |
Lazily loads the available providers of this loader's service. |
JavaFinalize() |
Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. (Inherited from Object) |
Load(Class, ClassLoader) |
Creates a new service loader for the given service type and class loader. |
Load(Class) |
Creates a new service loader for the given service type, using the current thread's java. |
LoadInstalled(Class) |
Creates a new service loader for the given service type, using the extension class loader. |
Notify() |
Wakes up a single thread that is waiting on this object's monitor. (Inherited from Object) |
NotifyAll() |
Wakes up all threads that are waiting on this object's monitor. (Inherited from Object) |
Reload() |
Clear this loader's provider cache so that all providers will be reloaded. |
SetHandle(IntPtr, JniHandleOwnership) |
Sets the Handle property. (Inherited from Object) |
ToArray<T>() | (Inherited from Object) |
ToString() |
Returns a string representation of the object. (Inherited from Object) |
UnregisterFromRuntime() | (Inherited from Object) |
Wait() |
Causes the current thread to wait until it is awakened, typically by being <em>notified</em> or <em>interrupted</em>. (Inherited from Object) |
Wait(Int64, Int32) |
Causes the current thread to wait until it is awakened, typically by being <em>notified</em> or <em>interrupted</em>, or until a certain amount of real time has elapsed. (Inherited from Object) |
Wait(Int64) |
Causes the current thread to wait until it is awakened, typically by being <em>notified</em> or <em>interrupted</em>, or until a certain amount of real time has elapsed. (Inherited from Object) |
Explicit Interface Implementations
IJavaPeerable.Disposed() | (Inherited from Object) |
IJavaPeerable.DisposeUnlessReferenced() | (Inherited from Object) |
IJavaPeerable.Finalized() | (Inherited from Object) |
IJavaPeerable.JniManagedPeerState | (Inherited from Object) |
IJavaPeerable.SetJniIdentityHashCode(Int32) | (Inherited from Object) |
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) | (Inherited from Object) |
IJavaPeerable.SetPeerReference(JniObjectReference) | (Inherited from Object) |
Extension Methods
JavaCast<TResult>(IJavaObject) |
Performs an Android runtime-checked type conversion. |
JavaCast<TResult>(IJavaObject) | |
GetJniTypeName(IJavaPeerable) |
Gets the JNI name of the type of the instance |
JavaAs<TResult>(IJavaPeerable) |
Try to coerce |
TryJavaCast<TResult>(IJavaPeerable, TResult) |
Try to coerce |
ToEnumerable(IIterable) | |
ToEnumerable<T>(IIterable) |