Contents

Google AutoService库简介

1. 简介

在本快速教程中,我们将简要介绍 Google 的 AutoService。

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

2.Java SPI

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

Java SPI 使用配置文件来查找和加载给定服务提供者接口的具体实现。即时定制应用程序是其主要功能之一。 另一方面,**添加或编辑配置文件很容易配置错误,也让我们有点困惑。**这一步也很容易忘记。

此外,总是存在我们可能不会注意到的拼写错误的风险,因为编译器不会考虑配置文件。

3. Google AutoService

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

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

3.1. Maven 设置

首先,让我们在我们的应用程序中添加Google AutoService 依赖项。我们可以将依赖项设置为optional,因为我们只在编译时需要它:

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

3.2. @AutoService示例

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

假设我们的应用程序具有翻译功能。我们的目标是使此功能可扩展。因此,我们可以轻松插入任何翻译服务提供商组件:

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

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

接下来,我们将使用*@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)"; 
    }
}

在编译的时候,AutoService 会查找注解并为每个对应的接口和实现生成一个配置文件。

因此,我们现在将拥有一个名为com.blogdemo.autoservice.TranslationService 的配置文件。此文件包含两个提供程序的完全限定名称:

com.blogdemo.autoservice.BingTranslationServiceProvider
com.blogdemo.autoservice.GoogleTranslationServiceProvider

3.3. @AutoService例子

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

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

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

让我们检查加载的提供程序计数:

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

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

所以现在,让我们选择一个提供者,然后调用服务方法来查看加载器是否按预期工作:

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));