Google AutoService – 谷歌自动服务

最后修改: 2019年 6月 23日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

In this quick tutorial, we’ll briefly explain Google’s AutoService.

在这个快速教程中,我们将简要地解释谷歌的自动服务。

This is an annotation processor library that helps us with generating Java Service Provider Interface (SPI) configuration files.

这是一个注释处理器库,可以帮助我们生成Java服务提供商接口(SPI)配置文件。

2. Java SPI

2.Java SPI

Simply put, we can leverage Java SPI to develop extensible applications, as it provides fast, safe, and also dynamic customizations.

简单地说,我们可以利用Java SPI来开发可扩展的应用程序,因为它提供了快速、安全、也是动态的定制。

Java SPI uses configuration files to find and load concrete implementations of given service provider interfaces. Customizing an application on the fly is one of its main capabilities.

Java SPI使用配置文件来查找和加载给定服务提供者接口的具体实现。即时定制一个应用程序是其主要功能之一。

On the other hand, it is easy to misconfigure and also a bit confusing for us to add or edit the configuration files. This step is also easy to forget.

另一方面,它很容易配置错误,也让我们在添加或编辑配置文件时有些困惑。这一步也很容易忘记。

Besides, there’s always a risk of typos that we may not notice, as the configuration files are not considered by the compiler.

此外,由于编译器不考虑配置文件,所以总是存在我们可能没有注意到的错别字的风险。

3. Google AutoService

3.谷歌自动服务

Google AutoService is an open source code generator tool, developed under the Google Auto project. There are also two other tools besides AutoService: AutoValue and AutoFactory.

Google AutoService是一个开源的代码生成工具,在Google Auto项目下开发。除了AutoService,还有另外两个工具。AutoValueAutoFactory

The purpose of this library is to save effort and time and, at the same time, to prevent misconfiguration.

本库的目的是为了节省精力和时间,同时,防止错误配置

3.1. Maven Setup

3.1.Maven设置

First, let’s add the auto-service dependency in our application. We can set the dependency as optional because we only need it at compile time:

首先,让我们在我们的应用程序中添加自动服务依赖。我们可以将该依赖关系设置为optional,因为我们只在编译时需要它。

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

3.2. @AutoService Example

3.2.@AutoService 示例

Second, we’ll create a service provider interface.

第二,我们将创建一个服务提供者接口。

Let’s assume that our application has a translation feature. We aim to make this feature extensible. So, we can plug in any translation service provider component easily:

让我们假设我们的应用程序有一个翻译功能。我们的目标是使这个功能具有可扩展性。因此,我们可以很容易地插入任何翻译服务提供者的组件。

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

Our application will use this interface as an extension point. An implementation on the classpath will be injected as a component.

我们的应用程序将使用这个接口作为一个扩展点。classpath上的一个实现将作为一个组件被注入。

Next, we’ll implement this service with two different translation providers using the @AutoService annotation:

接下来,我们将使用@AutoService注解,用两个不同的翻译提供者实现这个服务。

@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)"; 
    }
}

At the time of compilation, AutoService will look for the annotation and generate a configuration file for each of the corresponding interfaces and implementations.

在编译时,AutoService将寻找注释并为每个相应的接口和实现生成一个配置文件。

As a result, we’ll now have a configuration file named com.baeldung.autoservice.TranslationService. This file contains fully-qualified names of the two of the providers:

因此,我们现在会有一个名为com.baeldung.autoservice.TranslationService.的配置文件,该文件包含了两个提供者的全称名称。

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

3.3. @AutoService in Action

3.3.@AutoService在行动中

Now, everything is ready. Let’s load the providers through ServiceLoader:

现在,一切都准备好了。让我们通过ServiceLoader加载提供者。

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

The ServiceLoader will load every provider defined in the configuration file.

ServiceLoader将加载配置文件中定义的每个提供者。

Let’s check the loaded providers count:

让我们检查一下加载的提供者数量。

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

In other words, the ServiceLoader has loaded all of the provider instances. Therefore, it’s our job to select one of them.

换句话说,ServiceLoader已经加载了所有的提供者实例。因此,我们的工作是选择其中一个。

So now, let’s pick one of the providers and then call the service method to see whether 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

4.总结

In this article, we explained the Google AutoService library and also practiced with a simple example.

在这篇文章中,我们解释了Google AutoService库,还用一个简单的例子进行了练习。

Google AutoService is a useful but straightforward source code generator library. It saves us from creating and editing the service provider configuration files. It also guarantees that there won’t be any miswritten or mislocated files.

Google AutoService是一个有用但直接的源代码生成器库。它使我们免于创建和编辑服务提供者的配置文件。它还保证不会有任何误写或误定位的文件。

The source code of this tutorial is available on the GitHub project as usual.

本教程的源代码可在GitHub项目上照常获取。