简体   繁体   English

服务提供者接口(SPI)工作在 Java

[英]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 )返回一个EnumerationServiceLoader可以使用它来遍历所有配置文件并识别每个提供者。

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包括诸如acceptsURLgetMinorVersion / getMajorVersion等方法,应用程序可以使用这些方法来获取有关 Z82269B9B71AB4A7732F69581C 驱动程序的信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM