![[17.0.0.3 and later]](../ng_v17003plus.gif)
MicroProfile Config API
MicroProfile Config API は、異なるソースから構成情報を取得できる単一の API として、アプリケーションで使用できます。
- 複数の構成ソースを単一の構成に結合し、1 つの API でアクセスすることができます。
- 構成プロパティー値は、優先順位の高い値として指定された構成ソースの値でオーバーライドできます。
- 値は、指定されたプロパティー・ファイル、システム環境変数、および Java™ システム・プロパティーに保管できます。
- ConfigSource リソースは、Java ClassLoader (アプリケーションの現行コンテキスト ClassLoader またはユーザー指定の ClassLoader) を使用することでロードされます。
- ConfigSource インターフェースのユーザー実装環境を登録することで、値を指定できます。
- 標準装備またはカスタム・タイプのコンバーターを使用することで、値をストリングとして、または特定の Java クラスのタイプ付きオブジェクトとして取得することができます。
- ConfigSource および Converter の実装環境は、Java ServiceLoader パターンを使用して検出できます。
- プリミティブ、標準タイプ、ユーザー提供によるタイプのいずれかにかかわらず、構成プロパティー値は Java CDI (コンテキストおよび依存関係注入) を使用して直接注入できます。
構成の注入
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 がスローされます。
@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 インターフェースは、最初は空の構成プロパティー・ソースのセットを持っています。デフォルトのソースを追加すると、以下の影響があります。
- プロセス環境変数が構成に含まれます。Liberty は、ホスト・プロセス環境変数を Java System.getenv() メソッドに示し、さらにサーバーの server.env ファイルのプロパティーに追加します。これにより、これらの変数が MicroProfile Config API で使用可能になります。
- System.getProperties() 経由で使用可能な Java システム・プロパティーが構成内に含まれます。Liberty はサーバーの bootstrap.properties ファイルおよび jvm.options ファイルから Java システム・プロパティーにプロパティーを追加します。
- アプリケーションの ThreadContextClassLoader クラスパスから META-INF/microprofile-config.properties の resourceName と共にロードされたファイル。これらのプロパティー・ファイル内に、標準 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 パターンを使用してカスタム構成ソース・オブジェクトを見つけることもできます。${CLASSPATH}/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource の形式のファイルにフルパッケージ修飾クラス名がリストされている場合、ConfigSource インターフェースを実装するユーザー・クラスがロードされます。
コンバーター
MicroProfile Config API は、必要なプロパティー・オブジェクトのタイプを使用する一般化されたメソッドで、プロパティーを Java オブジェクト・タイプとして取得することもできます。このメソッドは、標準装備またはユーザー提供のコンバーターを持つ任意のタイプに対応できます。例えば、前述の例のコードは、標準装備のストリング・コンバーターを次のように使用するよう作成することができます。
appName = config.getOptionalValue(“APP_NAME”, String.class).orElse(“MicroDemo”);
標準装備コンバーター
MicroProfile Config API には、以下のタイプの標準装備コンバーターが組み込まれています。boolean、Boolean、int、Integer、long、Long、float、Float、double、Double、Duration、LocalTime、 LocalDate、LocalDateTime、OffsetDateTime、OffsetTime、Instant、および URL
これらのタイプの変数は、単一のストリング・パラメーターを使用して関連する valueof、parse、またはコンストラクター・メソッドを使用することでプロパティーのストリング値をそのタイプに正常に変換できれば、直接注入したり、一般化された getValue 呼び出しを使用して取得したりすることができます。
カスタム・コンバーター
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 によるコンバーターのサポート
${CLASSPATH}/META-INF/services/org.eclipse.microprofile.config.spi.Converter の形式のサービス・ファイルにパッケージの修飾クラス名が表示されている場合、Java ServiceLoader パターンを使用してカスタム・コンバーターを見つけることもできます。
MicroProfile Config API 実装に含まれたデフォルト・コンバーターも、Java ServiceLoader パターンを使用して検出されたコンバーターも、いずれもすべての構成で使用可能です。
プロパティー値のオーバーライド
複数の構成ソースが使用される場合、すべてのソースからのプロパティーがまとめて収集され、単一のセットとしてアプリケーションによってアクセスされます。各構成ソースには序数値が割り当てられます。1 つのプロパティーが複数のソースに出現する場合、最大序数のソースのプロパティー値が優先され、アプリケーションに返されます。 デフォルトの序数値は以下のとおりです。
- システム・プロパティー - 400
- 環境変数 - 300
- /META-INF/microprofile-config.properties - 100
- カスタム ConfigSource オブジェクト - ConfigSource の getOrdinal の結果
同じプロパティーを提供する 2 つの ConfigSources が同一の序数を持っている場合、ストリング比較ルールに従って ConfigSources ID を使用して比較が行われます。
開発ライフサイクルの早い段階で通常設定されるソースには、より低い序数と優先順位が設定されます。これは、アプリケーションのライフサイクルにおいて後で、例えばアプリケーションのアセンブリーやインストールの際に、既存のプロパティー値をオーバーライドする機能をサポートするためです。
動的プロパティー値
設計が工夫されたマイクロサービス・アプリケーションは個別のアプリケーションの再始動に左右されず可用性を維持しますが、構成値に対する変更についても再始動しなくてもアプリケーションで有効となるのが理想的です。登録済みの ConfigSource オブジェクトによって提供される、構成内のプロパティー値は、ConfigSources が提供する更新値によって更新できます。ConfigSources が調べられ、値が更新される頻度は、microprofile.config.refresh.rate Java システム・プロパティーで制御されます。使用される単位はミリ秒であり、デフォルト値は 500 です。 これは、デフォルトで、ConfigSources 提供の値が、それらの値が寄与する構成に 0.5 秒ほどで取り込まれることを意味します。
microprofile-config.properties ファイルなどの非プログラマチックな構成ソースは、最初の構成作成後に動的に再読み取りされません。
プロパティーの注入後に値の更新を表示できるようにするには、ConfigValue オブジェクトを使用できます。構成プロパティー値と構成プロパティー値の Optional<T> の両方において、これには getter があり、その getter が呼び出されるたびに現行値が返されます。以下に例を示します。
@Inject
@ConfigProperty(name="propertyName3")
Provider<MyClass> propertyName3;
MyClass mc = propertyName3.get();
また、ConfigValue クラスが一般化され、適切なコンバーターが存在すればこれを使用して特定のタイプのプロパティーを取得できることも確認できます。
Config のキャッシング
効率を促進するために、ConfigProvider は getConfig メソッドにより返された構成を、その ClassLoader により識別された特定のアプリケーション (モジュール) 用にキャッシュします。ConfigBuilder を使用して構成が生成される場合、その構成オブジェクトはキャッシュされません。ただし、org.eclipse.microprofile.config.spi パッケージ内の ConfigProviderResolver には、構成オブジェクトをキャッシュするために使用できる registerConfig メソッドと、構成オブジェクトをリリースするための releaseConfig メソッドが用意されています。
Liberty での MicroProfile Config の実装について詳しくは、MicroProfile Configuration プロジェクトのサイトを参照してください。