Google AutoService

1. 前書き

このクイックチュートリアルでは、GoogleのAutoServiceについて簡単に説明します。
これはlink:/java-annotation-processing-builder[annotation processor library]であり、https://www.baeldung.com/java-spi [Java Service Provider Interface]の生成に役立ちます( SPI)構成ファイル。

2. Java SPI

簡単に言えば、Java SPIを利用して拡張可能なアプリケーションを開発できます。これは、高速で安全かつ動的なカスタマイズを提供するためです。
  • Java SPIは、構成ファイルを使用して、特定のサービスプロバイダーインターフェイスの具体的な実装を検索およびロードします*。 その場でアプリケーションをカスタマイズすることは、その主な機能の1つです。

    一方、*設定の誤りは簡単であり、設定ファイルを追加または編集するのも少し混乱します。*このステップも忘れがちです。
    その上、構成ファイルはコンパイラーによって考慮されないため、気づかないかもしれないタイプミスのリスクが常にあります。

3. Google AutoService

https://github.com/google/auto/tree/master/service[Google AutoService]は、Google Autoプロジェクトの下で開発されたオープンソースコードジェネレーターツールです。 AutoService以外にも、https://www.baeldung.com/introduction-to-autovalue [AutoValue]とlink:/autofactory[AutoFactory]の2つのツールがあります。
*このライブラリの目的は、労力と時間を節約すること*であると同時に、*設定ミスを防ぐこと*です。

3.1. Mavenセットアップ

まず、アプリケーションにhttps://search.maven.org/search?q=g:com.google.auto.service%20AND%20a:auto-service&core=gav[auto-service]依存関係を追加しましょう。 コンパイル時にのみ必要なため、依存関係を_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_アノテーションを使用して、2つの異なる翻訳プロバイダーでこのサービスを実装します。
@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.baeldung.autoservice.TranslationService._という名前の構成ファイルが作成されます。このファイルには、2つのプロバイダーの完全修飾名が含まれています。
com.baeldung.autoservice.BingTranslationServiceProvider
com.baeldung.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_はすべてのプロバイダーインスタンスをロードしました。 したがって、そのうちの1つを選択するのが私たちの仕事です。
それでは、プロバイダーの1つを選択し、サービスメソッドを呼び出して、ローダーが期待どおりに動作するかどうかを確認しましょう。
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. 結論

この記事では、Google AutoServiceライブラリーについて説明し、簡単な例を使って練習しました。
Google AutoServiceは便利ですが、簡単なソースコードジェネレーターライブラリです。 *サービスプロバイダーの構成ファイルを作成および編集する必要がなくなります*。 また、誤って書き込まれたファイルや誤って配置されたファイルが存在しないことを保証します。
このチュートリアルのソースコードは、通常どおりhttps://github.com/eugenp/tutorials/tree/master/autovalue[the GitHubプロジェクト]で入手できます。