Using Google AutoService to Simplify Java SPI Implementations

This tutorial introduces Google AutoService, explains Java SPI concepts, shows Maven setup and @AutoService annotation examples, and demonstrates loading translation service providers with ServiceLoader, highlighting how the library automates SPI configuration and reduces errors.

Cognitive Technology Team
Cognitive Technology Team
Cognitive Technology Team
Using Google AutoService to Simplify Java SPI Implementations

1. Introduction

In this short tutorial we briefly introduce Google AutoService.

It is an annotation‑processor library that helps generate Java Service Provider Interface (SPI) configuration files.

2. Java SPI

Simply put, Java SPI allows us to develop extensible applications by providing fast, safe and dynamic customisation.

Java SPI uses configuration files to locate and load concrete implementations of a given service provider interface. One of its main capabilities is to enable runtime customisation of applications.

On the other hand, it is easy to misconfigure and we may feel confused when adding or editing configuration files. This step is also easy to forget.

Furthermore, because configuration files are not considered by the compiler, there is always a risk of unnoticed spelling errors.

Google AutoService is an open‑source code‑generation tool developed under the Google Auto project. In addition to AutoService, there are two other tools: AutoValue and AutoFactory.

The purpose of the library is to save effort and time , while preventing configuration errors .

3.1 Maven Configuration

First, add the auto‑service dependency to the project. The dependency can be marked as optional because it is only needed at compile time:

<dependency>
    <groupId>com.google.auto.service</groupId>
    <artifactId>auto-service</artifactId>
    <version>1.0-rc5</version>
    <optional>true</optional>
</dependency>

3.2 @AutoService Example

Next, we create a service provider interface.

Assume the application has a translation feature that we want to make extensible, so we can plug in any translation service provider component:

public interface TranslationService {
    String translate(String message, Locale from, Locale to);
}

The application will use this interface as an extension point; implementations on the classpath will be injected as components.

Now we use the @AutoService annotation to implement two different translation providers:

@AutoService(TranslationService.class)
public class BingTranslationServiceProvider implements TranslationService {
    @Override
    public String translate(String message, Locale from, Locale to) {
        // implementation details
        return message + " (translated by Bing)";
    }
}
@AutoService(TranslationService.class)
public class GoogleTranslationServiceProvider implements TranslationService {
    @Override
    public String translate(String message, Locale from, Locale to) {
        // implementation details
        return message + " (translated by Google)";
    }
}

During compilation AutoService discovers the annotations and generates a configuration file for each interface‑implementation pair.

Consequently we obtain a file named com.baeldung.autoservice.TranslationService that contains the fully‑qualified names of the two providers:

com.baeldung.autoservice.BingTranslationServiceProvider
com.baeldung.autoservice.GoogleTranslationServiceProvider

3.3 @AutoService in Practice

Now everything is ready. We load the providers using ServiceLoader :

ServiceLoader<TranslationService> loader = ServiceLoader.load(TranslationService.class);

ServiceLoader will load each provider defined in the configuration file.

We can check how many providers were loaded:

long count = StreamSupport.stream(loader.spliterator(), false).count();
assertEquals(2, count);

In other words, ServiceLoader has loaded all provider instances, and it is now our responsibility to choose one.

We select the Google provider and invoke its service method to verify the loader works as expected:

TranslationService googleService = StreamSupport.stream(loader.spliterator(), false)
    .filter(p -> p.getClass().getSimpleName().equals("GoogleTranslationServiceProvider"))
    .findFirst()
    .get();

String message = "message";

assertEquals(message + " (translated by Google)", googleService.translate(message, null, null));

4. Conclusion

In this article we explained the Google AutoService library and demonstrated it with a simple example.

Google AutoService is a useful yet simple source‑code generation library that spares us from creating and editing service provider configuration files and ensures that no spelling or file‑location errors occur.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavamavenSPIAnnotationProcessorAutoService
Cognitive Technology Team
Written by

Cognitive Technology Team

Cognitive Technology Team regularly delivers the latest IT news, original content, programming tutorials and experience sharing, with daily perks awaiting you.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.