MicroProfile Config API

MicroProfile Config API は、異なるソースから構成情報を取得できる単一の API として、アプリケーションで使用できます。

Open Liberty Liberty MicroProfile Config フィーチャーのバージョン 1.1 以降の使用については、 Open Liberty Web サイト を参照してください。

MicroProfile Config API を使用すると、以下のようになります。
  • 複数の構成ソースを単一の構成に結合し、1 つの API でアクセスすることができます。
  • 構成プロパティー値は、優先順位の高い値として指定された構成ソースの値でオーバーライドできます。
  • 値は、名前付きプロパティー・ファイル、システム環境変数、または Java™ システム・プロパティーに保管できます。
  • ConfigSource リソースは、Java ClassLoader(アプリケーションの現行コンテキスト ClassLoader またはユーザー提供の ClassLoader) を使用してロードされます。
  • ConfigSource インターフェースのユーザー実装環境を登録することで、値を指定できます。
  • 値は、組み込みまたはカスタム・タイプのコンバーターを使用して、ストリングとして、または特定の Java クラスの型付きオブジェクトとして取得できます。
  • ConfigSource 実装と Converter 実装は、Java ServiceLoader パターンを使用してディスカバーできます。
  • プリミティブ、標準タイプ、またはユーザー提供タイプのいずれの場合でも、構成プロパティー値は、Java CDI (Context and Dependency Injection) を使用して直接注入できます。

構成の注入

MicroProfile Config API は、Java ServiceLoader configsourcesによってロードされるデフォルトの構成ソースおよび構成ソースを収集します。これについては、このトピックで後述します。 Java CDI (Contexts and Dependency Injection) を使用して、構成オブジェクトをアプリケーションに直接注入することができます。

@Inject
Config config;
String appName = config.getValue("APP_NAME", String.class);

単一の構成プロパティー値を注入することも可能です。

@Inject
@ConfigProperty
String PROPERTY_NAME1;

これらのプロパティーは、標準の Java プロパティーと同様に、未加工形式でストリングとして表されます。 システムは構成ソースのデフォルト設定を使用し、classname の名前から構成プロパティーの名前を取得します。この名前は、最初の文字が小文字で、その後に変数名が付加されます。区切り記号はドットです。 例えば、直前のスニペットが ClassA というクラス内にある場合、解決されるプロパティー名は classA.PROPERTY_NAME1 です。

@Inject
@ConfigProperty(name="PROPERTY_NAME2")
String propertyTwo;

このコード・スニペットは、必須プロパティー PROPERTY_NAME2 を構成ソースから検索します。 このプロパティーが存在しない場合は DeploymentException がスローされます。

いずれの構成済み configsources にもプロパティーが存在しない場合は、defaultValue パラメーターを使用してデフォルト値を割り当てます。
@inject
@ConfigProperty(name="myName", defaultValue="Bob")
String name;
このコード・スニペットはプロパティー myName を構成済み configsources から検索します。 このプロパティーが未定義の場合は、値 Bob が変数 name に割り当てられます。

構成のプログラマチック検索

MicroProfile Config API は、メソッド呼び出しを使用して構成プロパティーを検索するためのインターフェースも提供します。 この検索を行う方法は 2 つあります。デフォルト設定を使用する使いやすい構成プロバイダー・クラスと、完全にカスタマイズ可能な構成ビルダー・クラスです。

ConfigProvider クラス

構成を使用する最も単純な方法は、ConfigProvider クラスで静的メソッドを使用することです。 この API は、Java ® ServiceLoader configsourcesによってロードされるデフォルトの構成ソースと構成ソースを収集します。

Config config = ConfigProvider.getConfig();
String appName = config.getValue("APP_NAME", String.class);

ConfigBuilder クラス

よりカスタマイズされた方法で構成を作成したいユーザーは、構成ビルダー API を使用して、構成の生成前にさまざまなオプションを設定することができます。 この例では、ビルダー・パターンを使用して、前の例の構成と同等の構成を作成しています。

ConfigBuilder builder = ConfigProviderResolver.getBuilder();
builder.addDefaultSources();
Config config = builder.build();

builder.addDefaultSources() を呼び出すと、構成を作成するために、ConfigProvider が使用するのと同じデフォルト・ソースのセットが追加されます。 その他の構成ソースも追加できます。

構成ソース

構成プロパティーは、プロパティー・ファイルや、アプリケーションによって登録されたユーザー・クラス、または Java ServiceLoader パターンを使用してロードされたユーザー・クラスなど、いくつかの場所から入手できます。

デフォルトのソース

ConfigProvider インターフェースと異なり、ConfigBuilder インターフェースは、最初は空の構成プロパティー・ソースのセットを持っています。 デフォルトのソースを追加すると、以下の影響があります。

  1. プロセス環境変数が構成に含まれます。 Liberty は、ホスト・プロセス環境変数を Java System.getenv() メソッドに示し、さらにサーバーの server.env ファイルからプロパティーを追加します。 これにより、これらの変数が MicroProfile Config API で使用可能になります。
  2. System.getProperties() 経由で使用可能な Java システム・プロパティーが構成に含まれています。 Liberty は、サーバーの bootstrap.properties ファイルおよび jvm.options ファイルから Java システム・プロパティーにプロパティーを追加します。
  3. resourceNameMETA-INF/microprofile-config.propertiesのアプリケーション ThreadContextClassLoader クラスパスからロードされるファイル。 これらのプロパティー・ファイル内では、プロパティーは、標準の Java プロパティー・ファイルで使用されるのと同じ構文を使用して保管されます。 Liberty アプリケーションの場合、 META-INF ディレクトリーの場所は、JAR のルートにあるサブディレクトリー、WAR ファイルの場合は WEB-INF\classes\META-INF\ ディレクトリー、EAR の lib ディレクトリーにある JAR、またはサーバー・レベルの共有ライブラリー JAR のいずれかになります。 使用される ClassLoader (クラスパス) は、ビルダーの forClassLoader メソッドを使用して変更できます。

ユーザー提供の ConfigSources

org.eclipse.microprofile.config.spi.ConfigSource を実装するユーザー・クラスを ConfigBuilder に登録することができます。 そのようにすると、このユーザー・クラスは、ビルダーが生成する構成に後で組み込まれます。

MySource source = new MySource();
builder.withSources(source);

ConfigSources の Java ServiceLoader ロード

Java ServiceLoader パターンを使用して、カスタム構成ソース・オブジェクトを見つけることもできます。 ConfigSource インターフェースを実装するユーザー・クラスは、その完全パッケージ修飾クラス名が ${CLASSPATH}/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSourceという形式のファイルにリストされている場合にロードされます。

コンバーター

MicroProfile Config API は、必要なプロパティー・オブジェクトのタイプを取得する汎化されたメソッドを使用して、プロパティーを Java オブジェクト・タイプとして取得することもできます。 このメソッドは、標準装備またはユーザー提供のコンバーターを持つ任意のタイプに対応できます。 例えば、前述の例のコードは、標準装備のストリング・コンバーターを次のように使用するよう作成することができます。

appName = config.getOptionalValue("APP_NAME", String.class).orElse("MicroDemo");

標準装備コンバーター

MicroProfile Config API には、 booleanBooleanintIntegerlongLongfloatFloatdoubleDoubleDurationLocalTimeLocalDateLocalDateTimeOffsetDateTimeOffsetTimeInstant、および URLの各タイプ用の組み込みコンバーターが含まれています。

これらのタイプの変数は、直接注入することも、汎用化された getValue 呼び出しを使用して取得することもできます。 該当する valueofparse、またはコンストラクター・メソッドを使用して、単一のストリング・パラメーターを取得することにより、プロパティーのストリング値をタイプに正常に変換できる場合。

カスタム・コンバーター

org.eclipse.microprofile.config.spi.Converter<T> インターフェースを実装するカスタム・コンバーターは、ConfigBuilder API を使用することで、構成に登録して使用することができます。

ConfigBuilder builder = ConfigProviderResolver.getBuilder();
builder.addDefaultSources();
Converter<CustomProperty> converter = new MyConverter(); 
builder.withConverters(converter);
Config config = builder.build();
Optional<CustomProperty> opt = config.getOptionalValue("PROPOBJ", CustomProperty.class);
withConverters メソッドは、リフレクションを使用してどのタイプのコンバーターが適切かを判別します。 Java Lambda コードは現在、十分なタイプ情報をリフレクション API に提供していないため、カスタム・コンバーターには Converter<T> インターフェースを明示的に実装するコードが必要です。

コンバーターの優先順位

同じタイプに対して複数のコンバーターが存在する場合、使用するコンバーターは @Priority アノテーションを使用して制御できます。 このメソッドを使用すると、アプリケーションのライフサイクルにおいて、コンバーターの実装を後でオーバーライドすることが可能です。 コンバーターは、優先順位の低い同じタイプの他のコンバーターをオーバーライドします。

import javax.annotation.Priority;
import org.eclipse.microprofile.config.spi.Converter;
@Priority(200)
publicclass StringPrefixConverter implements Converter<String> {
    @Override
    public String convert(String value) throws IllegalArgumentException {
        return"Converted:" + value;
    }
}

@Priority アノテーションを使用していない場合、コンバーターのデフォルト優先順位は 100 です。

Java ServiceLoader によるコンバーターのサポート

Java ServiceLoader パターンを使用して、カスタム・コンバーターのパッケージ修飾クラス名が ${CLASSPATH}/META-INF/services/org.eclipse.microprofile.config.spi.Converterという形式のサービス・ファイルに出現する場合に、カスタム・コンバーターを見つけることもできます。

MicroProfile Config API 実装に組み込まれているデフォルト・コンバーターと、Java ServiceLoader パターンを使用してディスカバーされたコンバーターの両方を、すべての構成で使用できます。

プロパティー値のオーバーライド

複数の構成ソースが使用される場合、すべてのソースからのプロパティーがまとめて収集され、単一のセットとしてアプリケーションによってアクセスされます。 各構成ソースには序数値が割り当てられます。 1 つのプロパティーが複数のソースに出現する場合、最大序数のソースのプロパティー値が優先され、アプリケーションに返されます。 デフォルトの序数値は以下のとおりです。

  • システム・プロパティー - 400
  • 環境変数 - 300
  • /META-INF/microprofile-config.properties - 100
  • カスタム ConfigSource オブジェクト - ConfigSourcegetOrdinal の結果
注: リストされている最初の 3 つの序数値は、適用先の構成ソースにある config_ordinal プロパティーを使用してオーバーライドできます。

同じプロパティーを提供する 2 つの ConfigSources が同一の序数を持っている場合、ストリング比較ルールに従って ConfigSources ID を使用して比較が行われます。

開発ライフサイクルの早い段階で通常設定されるソースには、より低い序数と優先順位が設定されます。 これは、アプリケーションのライフサイクルにおいて後で、例えばアプリケーションのアセンブリーやインストールの際に、既存のプロパティー値をオーバーライドする機能をサポートするためです。

動的プロパティー値

設計が工夫されたマイクロサービス・アプリケーションは個別のアプリケーションの再始動に左右されず可用性を維持しますが、構成値に対する変更についても再始動しなくてもアプリケーションで有効となるのが理想的です。

バージョン 1.4 より前のバージョンの mpConfig フィーチャーでは、登録済みの ConfigSource オブジェクトによって提供される構成内のプロパティー値は、ConfigSources が提供する更新値によって更新できます。 ConfigSources が参照され、値がリフレッシュされる頻度は、 microprofile.config.refresh.rate Java システム・プロパティーによって制御されます。 使用される単位はミリ秒であり、デフォルト値は 500 です。これは、デフォルトで、ConfigSources 提供の値が、それらの値が寄与する構成に 0.5 秒ほどで取り込まれることを意味します。 microprofile-config.properties ファイルなどの非プログラマチックな構成ソースは、最初の構成作成後に動的に再読み取りされません。

Open Liberty キャッシュされた値を MicroProfile 構成から取得する方法は、 mpConfig-1.4 フィーチャーで変更されました。 詳しくは、 Open Liberty ブログを参照してください。

プロパティーの注入後に値の更新を表示できるようにするには、ConfigValue オブジェクトを使用できます。 構成プロパティー値と構成プロパティー値の Optional<T> の両方において、これには getter があり、その getter が呼び出されるたびに現行値が返されます。 例:

@Inject
@ConfigProperty(name="propertyName3") 
Provider<MyClass> propertyName3;
MyClass mc = propertyName3.get();

また、ConfigValue クラスが一般化され、適切なコンバーターが存在すればこれを使用して特定のタイプのプロパティーを取得できることも確認できます。

Config のキャッシング

効率を促進するために、ConfigProvidergetConfig メソッドにより返された構成を、その ClassLoader により識別された特定のアプリケーション (モジュール) 用にキャッシュします。 ConfigBuilder を使用して構成が生成される場合、その構成オブジェクトはキャッシュされません。 ただし、 org.eclipse.microprofile.config.spi パッケージ内の ConfigProviderResolverには、Config オブジェクトをキャッシュに入れるために使用できる registerConfig メソッドと、Config オブジェクトを解放するための releaseConfig メソッドがあります。

Libertyでの MicroProfile Config の実装について詳しくは、 MicroProfile 構成プロジェクト・サイトを参照してください。