1. 序章

このクイックチュートリアルでは、GoogleのAutoServiceについて簡単に説明します。

これは、アノテーションプロセッサライブラリであり、 Javaサービスプロバイダインターフェイス(SPI)構成ファイルの生成に役立ちます。

2. Java SPI

簡単に言えば、Java SPIを活用して、高速で安全な動的なカスタマイズを提供する拡張可能なアプリケーションを開発できます。

Java SPIは、構成ファイルを使用して、特定のサービスプロバイダーインターフェイスの具体的な実装を見つけてロードします。 その場でアプリケーションをカスタマイズすることは、その主な機能の1つです。

一方、設定ミスが発生しやすく、設定ファイルの追加や編集が少し混乱します。この手順も忘れがちです。

さらに、構成ファイルはコンパイラーによって考慮されないため、タイプミスのリスクが常にあり、気付かない場合があります。

3. Google AutoService

Google AutoService は、GoogleAutoプロジェクトの下で開発されたオープンソースのコードジェネレータツールです。 AutoServiceの他に、AutoValueAutoFactoryの2つのツールもあります。

このライブラリの目的は、労力と時間を節約することと同時に、設定ミスを防ぐことです

3.1. Mavenのセットアップ

まず、アプリケーションにauto-service依存関係を追加しましょう。 コンパイル時にのみ必要になるため、依存関係をオプションとして設定できます。

<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は、便利ですが簡単なソースコードジェネレータライブラリです。 は、サービスプロバイダーの構成ファイルを作成および編集する手間を省きます。 また、ファイルの書き込みや場所の誤りがないことも保証されます。

このチュートリアルのソースコードは、通常どおりGitHubプロジェクトで入手できます。