服务提供者接口如何在Java中工作。我一直在使用JDBC,发现SPI负责加载Driver类。
以下行提供了Driver的实现类,我们可以使用iterator()对其进行迭代。
ServiceLoader.load(Driver.class); // returns the ServiceLoader for Driver class, we can iterate to get all implementation classes
我想知道这种方法在Java内部的工作原理。
答案 0 :(得分:1)
该课程提供了quite a bit of documentation。您是否还在寻找其他信息?
Java服务由服务jar中包含的服务提供商配置文件定义。该文件的名称基于服务接口的名称,类似于META-INF/services/com.example.CodecFactory
(使用ServiceLoader
文档中的示例)或META-INF/services/java.sql.Driver
(对于我认为的JDBC示例)您正在使用)。
这里要理解的关键是,特定服务的所有服务提供商配置文件都具有相同的名称。这意味着类路径包含多个具有该名称的资源,每个服务提供者一个。方法ClassLoader.getResources
(注意它是getResources
而不是getResource
)返回一个Enumeration
,ServiceLoader
可以用来遍历所有配置文件并标识每个提供程序。
每个配置文件仅包含实现类的名称。例如,如果您查看名为META-INF/services/java.sql.Driver
的Postgres jar,则其中只有一行:org.postgresql.Driver
。 ServiceLoader
只是从文件中读取实现类名称,然后先用类名称调用Class.forName
,然后再调用newInstance
创建实现类的实例,然后将其强制转换为{{ 1}}或任何服务接口。
如果应用程序需要有关每个服务提供商的更多信息,通常可以通过服务界面获取该信息。例如,接口java.sql.Driver
包含诸如java.sql.Driver
,acceptsURL
/ getMinorVersion
之类的方法,应用可以使用这些方法来获取有关JDBC驱动程序的信息。