1
votes

How Service Provider Interfaces work in Java. I have been working with JDBC and found out that SPI takes care for loading the Driver class.

The following line provides the implementation classes for Driver which we can iterate using 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.

1

1 Answers

1
votes

There's quite a bit of documentation provided with the class. Are you looking for information beyond that?

Services in Java are defined by a service provider configuration file included in the service 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).

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.

Each configuration file just contains the name of the implementation 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. 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.