このバージョンはまだ開発中であり、まだ安定しているとは見なされていません。最新の安定バージョンについては、Spring Boot 3.5.7 を使用してください! |
アノテーションプロセッサーを使用して独自のメタデータを生成する
spring-boot-configuration-processor jar を使用すると、@ConfigurationProperties (Javadoc) でアノテーションが付けられた項目から独自の構成メタデータファイルを簡単に生成できます。jar には、プロジェクトのコンパイル時に呼び出される Java アノテーションプロセッサーが含まれています。
アノテーションプロセッサーの構成
Maven を使用してビルドする場合は、コンパイラープラグイン (3.12.0 以降) を構成して、アノテーションプロセッサーパスに spring-boot-configuration-processor を追加します。
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>Gradle では、次の例に示すように、annotationProcessor 構成で依存関係を宣言する必要があります。
dependencies {
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
}additional-spring-configuration-metadata.json ファイルを使用している場合、compileJava タスクは、次の例に示すように、processResources タスクに依存するように構成する必要があります。
tasks.named('compileJava') {
inputs.files(tasks.named('processResources'))
}この依存関係により、コンパイル中にアノテーションプロセッサーが実行されるときに追加のメタデータが使用可能になります。
プロジェクトで AspectJ を使用している場合は、アノテーションプロセッサーが 1 回だけ実行されることを確認する必要があります。これを行うにはいくつかの方法があります。Maven を使用すると、 |
プロジェクトで Lombok を使用している場合は、そのアノテーションプロセッサーが |
自動メタデータ生成
プロセッサーは、@ConfigurationProperties (Javadoc) でアノテーションされたクラスとメソッドの両方を選択します。また、@ConfigurationPropertiesSource (Javadoc) でアノテーションされたクラスも選択します。
| これらのいずれかのアノテーションでメタアノテーションされたカスタムアノテーションはサポートされていません。 |
クラスにパラメーター化されたコンストラクターが 1 つある場合、コンストラクターに @Autowired (Javadoc) のアノテーションが付けられていない限り、コンストラクターパラメーターごとに 1 つのプロパティが作成されます。クラスに @ConstructorBinding (Javadoc) のアノテーションが明示的に付けられたコンストラクターがある場合、そのコンストラクターのコンストラクターパラメーターごとに 1 つのプロパティが作成されます。それ以外の場合、プロパティは、標準の getter および setter の存在によって検出され、コレクション型およびマップ型に対して特別な処理が行われます (getter のみが存在する場合でも検出されます)。アノテーションプロセッサーは、@Data (英語) 、@Value (英語) 、@Getter (英語) 、@Setter (英語) lombok アノテーションの使用もサポートします。
次の例を考えてみましょう。
Java
Kotlin
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("my.server")
public class MyServerProperties {
/**
* Name of the server.
*/
private String name;
/**
* IP address to listen to.
*/
private String ip = "127.0.0.1";
/**
* Port to listener to.
*/
private int port = 9797;
// getters/setters ...
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getIp() {
return this.ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPort() {
return this.port;
}
public void setPort(int port) {
this.port = port;
}
}import org.springframework.boot.context.properties.ConfigurationProperties
@ConfigurationProperties("my.server")
class MyServerProperties(
/**
* Name of the server.
*/
var name: String,
/**
* IP address to listen to.
*/
var ip: String = "127.0.0.1",
/**
* Port to listen to.
*/
var port: Int = 9797) これにより、my.server.name にはデフォルトがなく、my.server.ip および my.server.port のデフォルトはそれぞれ "127.0.0.1" および 9797 の 3 つのプロパティが公開されます。フィールドの Javadoc は、description 属性を設定するために使用されます。たとえば、my.server.ip の記述は「リッスンする IP アドレス」です。
description 属性は、型がコンパイル済みのソースコードとして利用可能な場合にのみ設定できます。型が依存関係からコンパイルされたクラスとしてのみ利用可能な場合は、この属性は設定されません。このような場合は、メタデータをソースとして取得するか、手動でエントリを入力してください。
@ConfigurationProperties (Javadoc) フィールドの Javadoc ではプレーンテキストのみを使用する必要があります。プレーンテキストは JSON に追加される前に処理されないためです。 |
レコードクラスで @ConfigurationProperties (Javadoc) を使用する場合、レコードコンポーネントの説明はクラスレベルの Javadoc タグ @param を介して提供される必要があります (レコードクラスには、通常のフィールドレベルの Javadoc を配置するための明示的なインスタンスフィールドはありません)。
アノテーションプロセッサーは、ソースモデルから既定値を抽出するために、いくつかのヒューリスティックを適用します。既定値は、型がコンパイルされているソースコードとして使用できる場合にのみ抽出できます。型が依存関係からコンパイルされたクラスとしてのみ使用できる場合は、既定値は抽出されません。さらに、既定値は静的に提供する必要があります。特に、別のクラスで定義された定数を参照しないでください。また、アノテーションプロセッサーは、Collections の既定値を自動検出できません。
デフォルト値を検出できなかった場合は、手動のメタデータを提供する必要があります。次の例について考えてみます。
Java
Kotlin
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("my.messaging")
public class MyMessagingProperties {
private List<String> addresses = new ArrayList<>(Arrays.asList("a", "b"));
private ContainerType containerType = ContainerType.SIMPLE;
// getters/setters ...
public List<String> getAddresses() {
return this.addresses;
}
public void setAddresses(List<String> addresses) {
this.addresses = addresses;
}
public ContainerType getContainerType() {
return this.containerType;
}
public void setContainerType(ContainerType containerType) {
this.containerType = containerType;
}
public enum ContainerType {
SIMPLE, DIRECT
}
}import org.springframework.boot.context.properties.ConfigurationProperties
import java.util.Arrays
@ConfigurationProperties("my.messaging")
class MyMessagingProperties(
val addresses: List<String> = ArrayList(Arrays.asList("a", "b")),
var containerType: ContainerType = ContainerType.SIMPLE) {
enum class ContainerType {
SIMPLE, DIRECT
}
}上記のクラスのプロパティのデフォルト値をドキュメント化するには、モジュールの手動メタデータに次のコンテンツを追加できます。
{"properties": [
{
"name": "my.messaging.addresses",
"defaultValue": ["a", "b"]
},
{
"name": "my.messaging.container-type",
"defaultValue": "simple"
}
]} 既存のプロパティの追加のメタデータをドキュメント化するには、プロパティの name のみが必要です。 |
ネストされたプロパティ
アノテーションプロセッサーは自動的に内部クラスをネストされたプロパティと見なします。名前空間のルートで ip と port をドキュメント化する代わりに、サブ名前空間を作成できます。更新された例を考えてみましょう:
Java
Kotlin
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("my.server")
public class MyServerProperties {
private String name;
private Host host;
// getters/setters ...
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Host getHost() {
return this.host;
}
public void setHost(Host host) {
this.host = host;
}
public static class Host {
private String ip;
private int port;
// getters/setters ...
public String getIp() {
return this.ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPort() {
return this.port;
}
public void setPort(int port) {
this.port = port;
}
}
}import org.springframework.boot.context.properties.ConfigurationProperties
@ConfigurationProperties("my.server")
class MyServerProperties(
var name: String,
var host: Host) {
class Host(val ip: String, val port: Int = 0)
} 上記の例では、my.server.name、my.server.host.ip、my.server.host.port プロパティのメタデータ情報が生成されます。フィールドまたは getter メソッドで @NestedConfigurationProperty (Javadoc) アノテーションを使用して、通常の (内部ではない) クラスをネストされているかのように扱う必要があることを示すことができます。
| これらの型は自動的に識別され、それぞれに対して単一のメタデータプロパティが生成されるため、これはコレクションやマップには影響しません。 |
構成プロパティソース
別のモジュールにある型が @ConfigurationProperties (Javadoc) アノテーション付き型で使用されている場合、一部のメタデータ要素は自動的に検出されません。上記の例を再利用すると、Host が別のモジュールにある場合、アノテーションプロセッサーは Host のソースにアクセスできないため、完全なメタデータは利用できません。
このユースケースを処理するには、Host 型を含むモジュールにアノテーションプロセッサーを追加し、@ConfigurationPropertiesSource (Javadoc) でアノテーションを付けます。
Java
Kotlin
import org.springframework.boot.context.properties.ConfigurationPropertiesSource;
@ConfigurationPropertiesSource
public class Host {
/**
* IP address to listen to.
*/
private String ip = "127.0.0.1";
/**
* Port to listener to.
*/
private int port = 9797;
// getters/setters ...
public String getIp() {
return this.ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPort() {
return this.port;
}
public void setPort(int port) {
this.port = port;
}
}import org.springframework.boot.context.properties.ConfigurationPropertiesScan
@ConfigurationPropertiesScan
class Host {
/**
* IP address to listen to.
*/
var ip: String = "127.0.0.1"
/**
* Port to listener to.
*/
var port = 9797
} これにより、META-INF/spring/configuration-metadata/com.example.Host.json 内の Host のメタデータが生成され、このような型を処理するときにアノテーションプロセッサーによって自動的に再利用されます。
@ConfigurationProperties (Javadoc) アノテーションが付けられた型が拡張する別のモジュールにある親クラスにアノテーションを付けることもできます。
| 制御していない型のメタデータを再利用する必要がある場合は、上記のパターンで名前が付けられたファイルを作成すると、クラスパスで使用できる限りそのファイルが使用されます。 |
メタデータを追加する
Spring Boot の構成ファイルの処理は非常に柔軟で、@ConfigurationProperties (Javadoc) Bean にバインドされていないプロパティが存在することがよくあります。また、既存のキーの一部の属性を調整したり、キーを完全に無視したりする必要がある場合もあります。このようなケースをサポートし、カスタムの「ヒント」を提供できるように、アノテーションプロセッサーは META-INF/additional-spring-configuration-metadata.json の項目をメインのメタデータファイルに自動的にマージします。
型のソースメタデータを生成するときに、その型のカスタムメタデータ (たとえば、META-INF/spring/configuration/metadata/com.example.SomeType.json 内の com.example.SomeType) を作成することもできます。
自動的に検出されたプロパティを参照する場合、説明、デフォルト値、非推奨情報は、指定されていれば上書きされます。手動プロパティ宣言が現在のモジュールで識別されない場合、新しいプロパティとして追加されます。
追加メタデータファイルの形式は通常の spring-configuration-metadata.json と全く同じです。"ignored.properties" セクションに含まれる項目は、生成された spring-configuration-metadata.json ファイルの "properties" セクションから削除されます。
追加のプロパティファイルはオプションです。追加のプロパティがない場合は、ファイルを追加しないでください。