Technology:
Service Provider Interface is an API proposed to be implemented or customized by a third-party provider. It can be used as an extension or be replaceable by existing implementations, making it a flexible choice for those looking to outsource Java development.
A Service is an extension of the set of interfaces, and a Service Provider is an implementation of the service. Classes in the provider category will generally implement the software testing service interface or expand the classes provided in the service. A Service Provider will provide a feature to customize the provider according to the requirements. Service Provider provides the feature to extend the service without modifying the original code base.
Installing Service Providers:
We can install service providers in two ways.
- These providers can be installed as plug-ins in the form of a JAR file and can copy to the classpath on the application, which means that service provider installation provides the application to the local.
- These providers can be installed as plug-ins in the form of a JAR file and copy the JAR file JRE/lib/ext folder in the JAVA_HOME path so that it will install on all the applications that this JDK is using, it is called global installation.
Loading Service providers:
After placing the service provider JAR, we need to inform JDK about the availability of the service provider, by creating the new file under META-INF/services folder in the application classpath.
We can help you by either installing the interface locally or globally based on your requirement.
The file name should be the fully qualified binary name of the service, and it will contain a list of fully qualified binary names of service provider classes.
Service Loader:
The main part of the Service Provider Interface is ServiceLoader class, which has the responsibility of discovering the loading the SPI implementations lazily, it used to scan the application classpath to discover the provider implementations and maintains in a cache.
Examples of SPI:
- java.util.spi.ConcurrencyNameProvider: provides the localized currency symbols for Currency.
- java.util.spi.LocaleNameProvider : provides the localized names for Locale.
- java.util.spi.TimeZoneNameProvider: provides the localized timeZone for Timezone.
- java.text.spi.DateFormatProvider: provides date and time formats for a specified locale.
- java.text.spi.NumberFormatProvider: provides monetary, integer and percentage values for the NumberFormat class.
These providers can be extended or replaced if the JDK implementation is not suitable for requirements.
Building Custom Service Provider:
We started by creating a maven project called hello-world-api.
Then create Service interface named HelloWorldService, that has to be implemented.
Lets create a main class for finding the service provider and execute the sayHello() method
If we run the App.java then it will produce any output.
Let’s create the HelloWorldService providers.
And if we run the App class then also produce the empty output as we have not specified the availability service provider.
Let’s create META-INF/services folder inside the src/main/resources folder.
Create a file named “org.sravan.spi.HelloWorldService” and add the below content into it.
org.sravan.spi.providers.HelloServiceProvider
Now if we run the App class files, then we can see the “Hello World” output same as the service provider returning.
Now let’s package this service Provider as JAR, by doing maven install.
Now let's create an extended version of HelloworldService Provider.
Create a new maven project named “hello-world-extended-api” and add the above project dependencies like below:
Create a new ExtendedHelloWorldServiceProvider that implements HelloWorldService interface.
Let’s create META-INF/services folder inside the src/main/resources folder.
Create a file named “org.sravan.spi.HelloWorldService” and add the below content into it.
org.sravan.extended.providers.ExtendedHelloWorldServiceProvider
Now if we execute the App class again, we observe the output from both Service Providers.
ServiceLoader has an overloaded method to load only the extended service provider using classloader.
ServiceLoader<S> load (Class<S> service,ClassLoader loader), we can write the custom classloader to load the classes from package.
Conclusion:
Java Development Company describe Service provider framework provides an easy way to decouple and load multiple service implementation of the given Service Interface. It is important to note that all Service Provider classes must be in the META-INF/services folder with the fully qualified name of the Service Interface.