S
-被这个加载器加载的服务类型
public final class ServiceLoader<S> extends Object implements Iterable<S>
一个服务是一个接口(通常是抽象类)。一个服务提供商是具体实施服务。在提供程序中的类通常实现了在服务本身定义的类的接口和子类。服务提供商可以安装在扩展,即形式的java平台的一个实现,JAR文件放置到任何常见的推广目录。供应商也可以通过将它们添加到应用程序的类路径或一些其他的平台特定的手段。
为加载的目的,服务由一个单一的类型表示,也就是一个单一的接口或抽象类。(一个具体的类可以使用,但不推荐这样做。)提供特定服务包含一个或多个具体的类,扩展服务类型数据和代码的提供程序特定的。的提供程序类通常不是整个提供商本身而是一个代理,包含足够的信息来决定是否提供能够满足特定的要求和代码,能根据需求创建实际的供应商。提供者类的细节往往是高度服务特定的,没有一个单一的类或接口可能会统一他们,所以没有这样的类型定义在这里。唯一的要求执行这种设施是提供程序类必须有一零个参数的构造函数,这样他们就可以被实例化时加载。
A service provider is identified by placing a provider-configuration file in the resource directory META-INF/services.文件的名称是服务的类型的完全限定binary name。该文件包含一个完全限定的具体提供类的二进制名称列表,每行一个。围绕每个名称的空格和制表符,以及空白行,都将被忽略。评论性'#'('\u0023',数字符号);每一行的所有字符的第一个评论的性格被忽略。该文件必须是UTF-8编码。
如果一个特定的具体的提供程序类以多个配置文件中的名字命名,或在同一配置文件中多次命名,则忽略重复的副本。配置文件命名一个特定的提供者不需要在同一个罐子文件或其他分发单元作为提供者本身。必须从最初查询的同一类装载器访问到定位配置文件,请注意,这不一定是该文件实际上是加载的类装载器。
供应商所在地和实例化,即需求。服务加载程序维护已加载到目前为止的供应商的缓存。每次调用的iterator
方法返回一个迭代器,首先产生的所有缓存的元素,在实例化,然后懒洋洋地定位并实例化任何剩余的供应商,加入每一个反过来的缓存。缓存可以通过reload
清除方法。
服务装载器总是在调用方的安全上下文中执行。可信系统的代码通常应该在这类调用的方法,以及这些方法返回的迭代器,在特权的安全上下文。
这个类的实例不安全使用多个并发线程。
除非另有规定,通过null争论在这个类中的任何方法会导致NullPointerException
被。
例子假设我们有一个服务型com.example.CodecSet旨在代表套编码器/解码器对一些协议。在这种情况下,它是一个抽象类,有两个抽象方法:
每个方法返回一个合适的对象或 null。典型的提供程序支持多个编码。public abstract Encoder getEncoder(String encodingName); public abstract Decoder getDecoder(String encodingName);
如果com.example.impl.StandardCodecs是实现的CodecSet服务那么它的jar文件还包含一个文件名为
META-INF/services/com.example.CodecSet
此文件包含单行:
com.example.impl.StandardCodecs # Standard codecs
的CodecSet类创建并保存在一个单一的服务实例的初始化:
private static ServiceLoader<CodecSet> codecSetLoader = ServiceLoader.load(CodecSet.class);
要找到一个给定的编码名称,它定义了一个静态工厂方法,遍历已知和可提供的编码器,还只有位于一个合适的编码器或已用完的提供者。
public static Encoder getEncoder(String encodingName) { for (CodecSet cp : codecSetLoader) { Encoder enc = cp.getEncoder(encodingName); if (enc != null) return enc; } return null; }
一个getDecoder方法类似的定义。
使用说明如果类加载器,用于提供加载类路径包括远程网络URL,然后这些网址将被引用在寻找供应商的配置文件。
此活动是正常的,虽然它可能会导致在Web服务器日志中创建的令人费解的条目。如果Web服务器配置不正确,但是,这个活动可以使供应商加载算法不误。
一个Web服务器应该返回一个HTTP 404(未找到)的反应时,所请求的资源不存在。有时,然而,Web服务器错误配置为返回一个HTTP 200(OK)随着帮助HTML错误页面,在这种情况下的反应。这将导致一个ServiceConfigurationError
被当这类试图解析HTML页面作为一个供应商的配置文件。这个问题最好的解决方法是把错误配置的Web服务器返回正确的响应代码(HTTP 404)随着HTML错误页面。
Modifier and Type | Method and Description |
---|---|
Iterator<S> |
iterator()
懒洋洋地负载可用此装载机服务提供商。
|
static <S> ServiceLoader<S> |
load(类<S> service)
创建一个新的服务程序对给定的服务类型,使用当前线程的
context class loader。
|
static <S> ServiceLoader<S> |
load(类<S> service, ClassLoader loader)
为给定的服务类型和类装载器创建一个新的服务装载器。
|
static <S> ServiceLoader<S> |
loadInstalled(类<S> service)
为给定的服务类型创建一个新的服务加载程序,使用扩展类加载程序。
|
void |
reload()
清除此装载机提供商缓存使所有供应商将重装上阵。
|
String |
toString()
返回描述此服务的字符串。
|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
forEach, spliterator
public void reload()
调用此方法后,后续的iterator
方法调用会懒洋洋地抬头实例化商从无到有,就像是一个新创建的程序做的。
这种方法适用的情况下,新的供应商可以安装到一个正在运行的java虚拟机。
public Iterator<S> iterator()
返回的迭代器的收益这一方法所有的提供商缓存的元素,在实例化顺序。然后,懒洋洋地加载和实例化任何剩余的供应商,加入每一个反过来的缓存。
实现懒惰解析可提供配置文件和实例化供应商实际工作必须由迭代器本身做。其hasNext
和next
方法可以因此如果提供程序配置文件违反指定的格式把ServiceConfigurationError
,或如果它的名字提供者类不能被发现和实例化,或者如果实例化类的结果是不可转让的服务类型,或者任何其他类型的异常或错误被作为下一个供应商所在地和实例化。编写健壮的代码会ServiceConfigurationError
使用迭代器时,服务才是必要的。
如果这种错误被随后的迭代器调用将尽最大努力找到并实例化的下一个可用的供应商,但总不能保证这样的恢复。
Design Note Throwing an error in these cases may seem extreme. The rationale for this behavior is that a malformed provider-configuration file, like a malformed class file, indicates a serious problem with the way the Java virtual machine is configured or is being used. As such it is preferable to throw an error rather than try to recover or, even worse, fail silently.
该方法返回的迭代器不支持移除。调用其remove
方法会造成UnsupportedOperationException
被。
iterator
接口
Iterable<S>
Iterator
过程的顺序,
ClassLoader.getResources(String)
方法找到服务配置文件。
public static <S> ServiceLoader<S> load(类<S> service, ClassLoader loader)
S
-服务型课堂
service
-接口或抽象类表示服务
loader
的类加载器来加载提供了配置文件提供程序类,或
null如果系统类装载器(或,否则,引导类装入器)是用于
public static <S> ServiceLoader<S> load(类<S> service)
这种方便的形式方法的调用
相当于ServiceLoader.load(service)
ServiceLoader.load(service, Thread.currentThread().getContextClassLoader())
S
-服务型课堂
service
-接口或抽象类表示服务
public static <S> ServiceLoader<S> loadInstalled(类<S> service)
这个方法简单方便地扩展类装载器,把它extClassLoader,然后返回
ServiceLoader.load(service, extClassLoader)
如果不能找到扩展类装载器,则使用系统类装载器;如果没有系统类装载器,则使用自举类装载器。
此方法的目的是为只需安装的供应商时使用。由此产生的服务只会找到并加载机构已安装到当前的java虚拟机;对应用程序的类路径提供者将被忽略。
S
-服务型课堂
service
-接口或抽象类表示服务
Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2014, Oracle and/or its affiliates. All rights reserved.