[英]Service Provider Interface(SPI) working in Java
How Service Provider Interfaces work in Java.服务提供者接口如何在 Java 中工作。 I have been working with JDBC and found out that SPI takes care for loading the Driver class.
我一直在使用 JDBC 并发现 SPI 负责加载驱动程序 class。
The following line provides the implementation classes for Driver which we can iterate using iterator().以下行提供了 Driver 的实现类,我们可以使用 iterator() 对其进行迭代。
ServiceLoader.load(Driver.class); // returns the ServiceLoader for Driver class, we can iterate to get all implementation classes
I wanted to know how this method works internally in Java.我想知道这种方法在 Java 内部是如何工作的。
There's quite a bit of documentation provided with the class. class 提供了相当多的文档。 Are you looking for information beyond that?
您是否正在寻找除此之外的信息?
Services in Java are defined by a service provider configuration file included in the service jar. Java 中的服务由服务 jar 中包含的服务提供者配置文件定义。 The name of this file based on the name of the service interface and is something like
META-INF/services/com.example.CodecFactory
(to use the example from the ServiceLoader
documentation) or META-INF/services/java.sql.Driver
(for the JDBC example that I think you're using).此文件的名称基于服务接口的名称,类似于
META-INF/services/com.example.CodecFactory
(使用ServiceLoader
文档中的示例)或META-INF/services/java.sql.Driver
(对于我认为您正在使用的 JDBC 示例)。
The key thing to understand here is that all the service provider configuration files for a particular service have the same name.这里要理解的关键是特定服务的所有服务提供者配置文件都具有相同的名称。 That means that the classpath contains multiple resources with that name, one per service provider.
这意味着类路径包含多个具有该名称的资源,每个服务提供者一个。 The method
ClassLoader.getResources
(note it's getResources
not getResource
) returns a Enumeration
that ServiceLoader
can use to iterate over all of the config files and identify each provider.方法
ClassLoader.getResources
(注意它是getResources
不是getResource
)返回一个Enumeration
, ServiceLoader
可以使用它来遍历所有配置文件并识别每个提供者。
Each configuration file just contains the name of the implementation class.每个配置文件只包含实现 class 的名称。 If you look at the Postgres jar, for example, which is named
META-INF/services/java.sql.Driver
, it just has one line: org.postgresql.Driver
.例如,如果你查看 Postgres jar,它被命名为
META-INF/services/java.sql.Driver
,它只有一行: org.postgresql.Driver
ServiceLoader
just reads the implementation class name from the file, then calls Class.forName
with the class name and then newInstance
to create an instance of the implementation class, which it can then cast to java.sql.Driver
or whatever the service interface is. ServiceLoader
just reads the implementation class name from the file, then calls Class.forName
with the class name and then newInstance
to create an instance of the implementation class, which it can then cast to java.sql.Driver
or whatever the service interface is.
If the app needs more information about each service provider, it can usually get that information through the service interface.如果应用程序需要有关每个服务提供者的更多信息,它通常可以通过服务接口获取该信息。 For example, the interface
java.sql.Driver
includes methods like acceptsURL
, getMinorVersion
/ getMajorVersion
, etc. that the app can use to get information about JDBC drivers.例如,接口
java.sql.Driver
包括诸如acceptsURL
、 getMinorVersion
/ getMajorVersion
等方法,应用程序可以使用这些方法来获取有关 Z82269B9B71AB4A7732F69581C 驱动程序的信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.