The java.util.ServiceLoader class in Java provides a simple mechanism for discovering and loading Implementations of a service interface from the classpath. It is part of the Java Standard Library and is often used in modular or plugin-based applications where different implementations of a service interface may be available.
Here's how ServiceLoader works:
1. Service Provider Interface
First, you define a service interface that represents a contract or API. This interface defines the methods or behaviour that implementations must adhere to.
To demonstrate the example, I defined a log-service project, and it has LogService interface.
LogService.java
package com.sample.app.log.service;
public interface LogService {
void log(String msg);
}
2. Service Provider Implementations
Next, you create one or more implementations of the service interface. These implementations are typically packaged as JAR files and made available in the classpath.
To demonstrate the example, I defined two libraries sdk1, and sdk2 which implement LogService interface.
Example
public class Sdk1Logger implements LogService {
@Override
public void log(String msg) {
System.out.println("From Sdk1Logger " + new Date() + " : " + msg);
}
}
3. Service Configuration File
Include a special file named META-INF/services/{fully-qualified-service-interface-name} in the JAR files containing the implementations. This file lists the fully qualified class names of the service provider implementations, one per line.
com.sample.app.log.service.LogService
com.sample.app.sdk1.log.service.Sdk1Logger
4. Service Loading
At runtime, you use the ServiceLoader class to dynamically load implementations of the service interface. The ServiceLoader class reads the service configuration files from the classpath and instantiates the service provider implementations.
ServiceLoaderlogServicesLoader = ServiceLoader.load(LogService.class);
5. Iterating Over Implementations
You can then iterate over the loaded service provider implementations using the iterator() method of ServiceLoader. This returns an iterator that provides access to the instantiated service provider objects.Iterator logServiceIterator = logServicesLoader.iterator();
while (logServiceIterator.hasNext()) {
LogService logService = logServiceIterator.next();
logService.log("Hello World");
}
Find the below step-by-step procedure to build the working application.
log-service project setup
Create new maven project ‘log-service’ and update pom.xml like below.
pom.xml
project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
modelVersion>4.0.0modelVersion>
groupId>com.sample.appgroupId>
artifactId>log-serviceartifactId>
version>1.0.0version>
build>
plugins>
plugin>
groupId>org.apache.maven.pluginsgroupId>
artifactId>maven-surefire-pluginartifactId>
version>3.0.0-M6version>
plugin>
plugin>
groupId>org.apache.maven.pluginsgroupId>
artifactId>maven-release-pluginartifactId>
version>2.5.3version>
configuration>
localCheckout>truelocalCheckout>
autoVersionSubmodules>trueautoVersionSubmodules>
configuration>
plugin>
plugins>
build>
project>
Define LogService interface.
LogService.java
package com.sample.app.log.service;
public interface LogService {
void log(String msg);
}
Setup sdk1
Create sdk1 maven project and update pom.xml like below.
pom.xml
project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
modelVersion>4.0.0modelVersion>
groupId>com.sample.appgroupId>
artifactId>sdk1artifactId>
version>1.0.0version>
dependencies>
dependency>
groupId>com.sample.appgroupId>
artifactId>log-serviceartifactId>
version>1.0.0version>
dependency>
dependencies>
build>
plugins>
plugin>
groupId>org.apache.maven.pluginsgroupId>
artifactId>maven-surefire-pluginartifactId>
version>3.0.0-M6version>
plugin>
plugin>
groupId>org.apache.maven.pluginsgroupId>
artifactId>maven-release-pluginartifactId>
version>2.5.3version>
configuration>
localCheckout>truelocalCheckout>
autoVersionSubmodules>trueautoVersionSubmodules>
configuration>
plugin>
plugins>
build>
project>
Define Sdk1Logger class.
Sdk1Logger.java
package com.sample.app.sdk1.log.service;
import java.util.Date;
import com.sample.app.log.service.LogService;
public class Sdk1Logger implements LogService {
@Override
public void log(String msg) {
System.out.println("From Sdk1Logger " + new Date() + " : " + msg);
}
}
Create a file 'com.sample.app.log.service.LogService' in src/main/resources/META-INF/services folder of sdk1 project.
com.sample.app.log.service.LogService
com.sample.app.sdk1.log.service.Sdk1Logger
sdk2 project setup
Create a new maven project sdk2 and update pom.xml with maven dependencies.
pom.xml
project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
modelVersion>4.0.0modelVersion>
groupId>com.sample.appgroupId>
artifactId>sdk2artifactId>
version>1.0.0version>
dependencies>
dependency>
groupId>com.sample.appgroupId>
artifactId>log-serviceartifactId>
version>1.0.0version>
dependency>
dependencies>
build>
plugins>
plugin>
groupId>org.apache.maven.pluginsgroupId>
artifactId>maven-surefire-pluginartifactId>
version>3.0.0-M6version>
plugin>
plugin>
groupId>org.apache.maven.pluginsgroupId>
artifactId>maven-release-pluginartifactId>
version>2.5.3version>
configuration>
localCheckout>truelocalCheckout>
autoVersionSubmodules>trueautoVersionSubmodules>
configuration>
plugin>
plugins>
build>
project>
Define Sdk2Logger class.
Sdk2Logger.java
package com.sample.app.sdk2.log.service;
import com.sample.app.log.service.LogService;
This post first appeared on Java Tutorial : Blog To Learn Java Programming, please read the originial post: here