Spring Boot jar には、サポートされているすべての構成プロパティの詳細を提供するメタデータファイルが含まれています。ファイルは、ユーザーが application.properties
または application.yml
ファイルを操作しているときに、IDE 開発者がコンテキストヘルプと「コード補完」を提供できるように設計されています。
メタデータファイルの大部分は、@ConfigurationProperties
アノテーションが付けられたすべてのアイテムを処理することにより、コンパイル時に自動的に生成されます。ただし、コーナーケースまたはより高度なユースケースのメタデータの一部を手動で書き込むことは可能です。
1. メタデータ形式
構成メタデータファイルは META-INF/spring-configuration-metadata.json
の jar 内にあります。次の例に示すように、JSON 形式を使用して、「グループ」または「プロパティ」のいずれかに分類された項目と、「ヒント」に分類された追加の値のヒントを使用します。
{"groups": [
{
"name": "server",
"type": "org.springframework.boot.autoconfigure.web.ServerProperties",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},
{
"name": "spring.jpa.hibernate",
"type": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate",
"sourceType": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties",
"sourceMethod": "getHibernate()"
}
...
],"properties": [
{
"name": "server.port",
"type": "java.lang.Integer",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},
{
"name": "server.address",
"type": "java.net.InetAddress",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},
{
"name": "spring.jpa.hibernate.ddl-auto",
"type": "java.lang.String",
"description": "DDL mode. This is actually a shortcut for the \"hibernate.hbm2ddl.auto\" property.",
"sourceType": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate"
}
...
],"hints": [
{
"name": "spring.jpa.hibernate.ddl-auto",
"values": [
{
"value": "none",
"description": "Disable DDL handling."
},
{
"value": "validate",
"description": "Validate the schema, make no changes to the database."
},
{
"value": "update",
"description": "Update the schema if necessary."
},
{
"value": "create",
"description": "Create the schema and destroy previous data."
},
{
"value": "create-drop",
"description": "Create and then destroy the schema at the end of the session."
}
]
}
]}
各「プロパティ」は、ユーザーが指定された値で指定する構成アイテムです。例: server.port
および server.address
は、次のように application.properties
/application.yaml
で指定される場合があります。
server.port=9090
server.address=127.0.0.1
server:
port: 9090
address: 127.0.0.1
「グループ」は、それ自体が値を指定するのではなく、プロパティのコンテキストグループを提供する上位レベルのアイテムです。例: server.port
および server.address
プロパティは server
グループの一部です。
すべての「プロパティ」に「グループ」がある必要はありません。一部のプロパティはそれ自体で存在する場合があります。 |
最後に、「ヒント」は、ユーザーが特定のプロパティを構成するのを支援するために使用される追加情報です。例: 開発者が spring.jpa.hibernate.ddl-auto
プロパティを構成している場合、ツールはヒントを使用して none
、validate
、update
、create
、create-drop
値の自動補完ヘルプを提供できます。
1.1. グループ属性
groups
配列に含まれる JSON オブジェクトには、次の表に示す属性を含めることができます。
名前 | タイプ | 目的 |
---|---|---|
| String | グループのフルネーム。この属性は必須です。 |
| String | グループのデータ型のクラス名。例: グループが |
| String | ユーザーに表示できるグループの簡単な説明。説明がない場合は、省略できます。説明は短いパラグラフにすることをお勧めします。最初の行は簡潔な要約を提供します。説明の最後の行はピリオド( |
| String | このグループに貢献したソースのクラス名。例: グループが |
| String | このグループに貢献したメソッドのフルネーム(括弧と引数型を含む)(たとえば、 |
1.2. プロパティ属性
properties
配列に含まれる JSON オブジェクトには、次の表で説明する属性を含めることができます。
名前 | タイプ | 目的 |
---|---|---|
| String | プロパティの完全な名前。名前は小文字のピリオド区切り形式です(たとえば、 |
| String | プロパティのデータ型の完全な署名(例: |
| String | ユーザーに表示できるプロパティの簡単な説明。説明がない場合は、省略できます。説明は短いパラグラフにすることをお勧めします。最初の行は簡潔な要約を提供します。説明の最後の行はピリオド( |
| String | このプロパティを提供したソースのクラス名。例: プロパティが |
| オブジェクト | デフォルト値。プロパティが指定されていない場合に使用されます。プロパティの型が配列の場合、値の配列にすることができます。デフォルト値が不明な場合、省略できます。 |
| 使用すべきではない | プロパティが廃止されるかどうかを指定します。フィールドが非推奨でない場合、またはその情報が不明な場合は、省略できます。次の表に、 |
各 properties
要素の deprecation
属性に含まれる JSON オブジェクトには、次の属性を含めることができます。
名前 | タイプ | 目的 |
---|---|---|
| String | 非推奨のレベル。 |
| String | プロパティが廃止された理由の簡単な説明。理由がない場合は、省略できます。説明は短いパラグラフにすることをお勧めします。最初の行は簡潔な要約を提供します。説明の最後の行はピリオド( |
| String | この廃止されたプロパティを置き換えるプロパティの完全な名前。このプロパティの代替がない場合は、省略できます。 |
Spring Boot 1.3 以前は、deprecation 要素の代わりに単一の deprecated ブール属性を使用できました。これは現在も非推奨の方法でサポートされており、今後は使用しないでください。理由と置換がない場合は、空の deprecation オブジェクトを設定する必要があります。 |
非推奨は、非推奨プロパティを公開する getter に @DeprecatedConfigurationProperty
アノテーションを追加することにより、コードで宣言的に指定することもできます。たとえば、my.app.target
プロパティが混乱し、my.app.name
に名前が変更されたと仮定します。次の例は、その状況を処理する方法を示しています。
@ConfigurationProperties("my.app")
public class MyProperties {
private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@Deprecated
@DeprecatedConfigurationProperty(replacement = "my.app.name")
public String getTarget() {
return this.name;
}
@Deprecated
public void setTarget(String target) {
this.name = target;
}
}
level を設定する方法はありません。コードがまだプロパティを処理しているため、warning が常に想定されます。 |
上記のコードは、廃止されたプロパティが引き続き機能することを確認します(バックグラウンドで name
プロパティに委譲します)。getTarget
および setTarget
メソッドがパブリック API から削除されると、メタデータの自動非推奨ヒントもなくなります。ヒントを保持したい場合は、error
非推奨レベルの手動メタデータを追加することで、ユーザーにそのプロパティについての情報を確実に提供できます。これは、replacement
が提供されている場合に特に役立ちます。
1.3. ヒント属性
hints
配列に含まれる JSON オブジェクトには、次の表に示す属性を含めることができます。
名前 | タイプ | 目的 |
---|---|---|
| String | このヒントが参照するプロパティの完全な名前。名前は小文字のピリオド区切り形式です( |
| ValueHint[] |
|
| ValueProvider[] |
|
各 hint
要素の values
属性に含まれる JSON オブジェクトには、次の表で説明する属性を含めることができます。
名前 | タイプ | 目的 |
---|---|---|
| オブジェクト | ヒントが参照する要素の有効な値。プロパティの型が配列の場合、値の配列にすることもできます。この属性は必須です。 |
| String | ユーザーに表示できる値の簡単な説明。説明がない場合は、省略できます。説明は短いパラグラフにすることをお勧めします。最初の行は簡潔な要約を提供します。説明の最後の行はピリオド( |
各 hint
要素の providers
属性に含まれる JSON オブジェクトには、次の表で説明する属性を含めることができます。
名前 | タイプ | 目的 |
---|---|---|
| String | ヒントが参照する要素に追加のコンテンツ支援を提供するために使用するプロバイダーの名前。 |
| JSON オブジェクト | プロバイダーがサポートする追加パラメーター(詳細については、プロバイダーのドキュメントを確認してください)。 |
2. 手動ヒントの提供
ユーザーエクスペリエンスを向上させ、特定のプロパティの構成をさらに支援するために、次の追加のメタデータを提供できます。
プロパティの潜在的な値のリストを記述します。
ツールがプロジェクトのコンテキストに基づいて潜在的な値のリストを検出できるように、プロバイダーを関連付けて、明確に定義されたセマンティクスをプロパティに関連付けます。
2.1. 値ヒント
各ヒントの name
属性は、プロパティの name
を参照します。前に示した最初の例では、spring.jpa.hibernate.ddl-auto
プロパティに 5 つの値 none
、validate
、update
、create
、create-drop
を提供します。各値には説明も含まれる場合があります。
プロパティの型が Map
の場合、キーと値の両方にヒントを提供できます(ただし、マップ自体には提供できません)。特別な .keys
および .values
サフィックスは、それぞれキーと値を参照する必要があります。
次の例に示すように、my.contexts
がマジック String
値を整数にマッピングすると仮定します。
@ConfigurationProperties("my")
public class MyProperties {
private Map<String, Integer> contexts;
}
マジック値は(この例では) sample1
と sample2
です。キーの追加コンテンツ支援を提供するために、次の JSON をモジュールの手動メタデータに追加できます。
{"hints": [
{
"name": "my.contexts.keys",
"values": [
{
"value": "sample1"
},
{
"value": "sample2"
}
]
}
]}
代わりに、これら 2 つの値に Enum を使用することをお勧めします。IDE がサポートしている場合、これが自動補完への最も効果的なアプローチです。 |
2.2. バリュープロバイダー
プロバイダーは、セマンティクスをプロパティに付加する強力な方法です。このセクションでは、独自のヒントに使用できる公式プロバイダーを定義します。ただし、お気に入りの IDE はこれらの一部を実装する場合と、まったく実装しない場合があります。また、最終的には独自のものを提供できます。
これは新しい機能であるため、IDE ベンダーはその機能に追いつく必要があります。採用時間は当然異なります。 |
次の表は、サポートされるプロバイダーのリストをまとめたものです。
名前 | 説明 |
---|---|
| 追加の値の提供を許可します。 |
| プロジェクトで使用可能なクラスを自動補完します。通常、 |
| 必須の |
| 有効なロガー名とロガーグループを自動補完します。通常、現在のプロジェクトで使用可能なパッケージ名とクラス名は、定義済みグループと同様に自動補完できます。 |
| 現在のプロジェクトで使用可能な Bean 名を自動補完します。通常、 |
| プロジェクトで使用可能な Spring プロファイル名を自動補完します。 |
特定のプロパティに対してアクティブにできるプロバイダーは 1 つだけですが、すべてのプロバイダーが何らかの方法でプロパティを管理できる場合は、複数のプロバイダーを指定できます。IDE は処理可能な JSON セクションの最初のプロバイダーを使用する必要があるため、最も強力なプロバイダーを最初に配置してください。特定のプロパティのプロバイダーがサポートされていない場合、特別なコンテンツ支援も提供されません。 |
2.2.1. 任意
特別な any provider 値により、追加の値を提供できます。サポートされている場合は、プロパティ型に基づいた定期的な値検証を適用する必要があります。
通常、このプロバイダーは、値のリストがあり、追加の値が有効であると見なされる場合に使用されます。
次の例は、system.state
の自動補完値として on
および off
を提供しています。
{"hints": [
{
"name": "system.state",
"values": [
{
"value": "on"
},
{
"value": "off"
}
],
"providers": [
{
"name": "any"
}
]
}
]}
上記の例では、他の値も許可されています。
2.2.2. クラス参照
クラス参照プロバイダーは、プロジェクトで使用可能なクラスを自動補完します。このプロバイダーは、次のパラメーターをサポートしています。
パラメーター | タイプ | デフォルト値 | 説明 |
---|---|---|---|
|
|
none |
The fully qualified name of the class that should be assignable to the chosen value. Typically used to filter out-non candidate classes. Note that this information can be provided by the type itself by exposing a class with the appropriate upper bound. |
|
| true | 具象クラスのみを有効な候補と見なすかどうかを指定します。 |
次のメタデータスニペットは、使用する JspServlet
クラス名を定義する標準 server.servlet.jsp.class-name
プロパティに対応しています。
{"hints": [
{
"name": "server.servlet.jsp.class-name",
"providers": [
{
"name": "class-reference",
"parameters": {
"target": "javax.servlet.http.HttpServlet"
}
}
]
}
]}
2.2.3. ハンドル
handle-as プロバイダーを使用すると、プロパティの型をより高レベルの型に置き換えることができます。これは通常、プロパティが java.lang.String
型の場合に発生します。これは、構成クラスがクラスパス上にない可能性のあるクラスに依存しないようにするためです。このプロバイダーは、次のパラメーターをサポートしています。
パラメーター | タイプ | デフォルト値 | 説明 |
---|---|---|---|
|
|
none |
The fully qualified name of the type to consider for the property. This parameter is mandatory. |
The following types can be used:
-
Any
java.lang.Enum
: Lists the possible values for the property. (We recommend defining the property with theEnum
type, as no further hint should be required for the IDE to auto-complete the values) -
java.nio.charset.Charset
: Supports auto-completion of charset/encoding values (such asUTF-8
) -
java.util.Locale
: auto-completion of locales (such asen_US
) -
org.springframework.util.MimeType
: Supports auto-completion of content type values (such astext/plain
) -
org.springframework.core.io.Resource
: Supports auto-completion of Spring’s Resource abstraction to refer to a file on the filesystem or on the classpath (such asclasspath:/sample.properties
)
If multiple values can be provided, use a Collection or Array type to teach the IDE about it.
|
The following metadata snippet corresponds to the standard spring.liquibase.change-log
property that defines the path to the changelog to use.
It is actually used internally as a org.springframework.core.io.Resource
but cannot be exposed as such, because we need to keep the original String value to pass it to the Liquibase API.
{"hints": [
{
"name": "spring.liquibase.change-log",
"providers": [
{
"name": "handle-as",
"parameters": {
"target": "org.springframework.core.io.Resource"
}
}
]
}
]}
2.2.4. Logger Name
The logger-name provider auto-completes valid logger names and logger groups. Typically, package and class names available in the current project can be auto-completed. If groups are enabled (default) and if a custom logger group is identified in the configuration, auto-completion for it should be provided. Specific frameworks may have extra magic logger names that can be supported as well.
This provider supports the following parameters:
Parameter | Type | Default value | Description |
---|---|---|---|
|
|
| 既知のグループを考慮するかどうかを指定します。 |
ロガー名は任意の名前にすることができるため、このプロバイダーは任意の値を許可する必要がありますが、プロジェクトのクラスパスで使用できない有効なパッケージ名とクラス名を強調表示できます。
次のメタデータスニペットは、標準の logging.level
プロパティに対応しています。キーはロガー名であり、値は標準ログレベルまたは任意のカスタムレベルに対応します。Spring Boot にはすぐに使用できるロガーグループがいくつか定義されているため、専用の値ヒントが追加されています。
{"hints": [
{
"name": "logging.level.keys",
"values": [
{
"value": "root",
"description": "Root logger used to assign the default logging level."
},
{
"value": "sql",
"description": "SQL logging group including Hibernate SQL logger."
},
{
"value": "web",
"description": "Web logging group including codecs."
}
],
"providers": [
{
"name": "logger-name"
}
]
},
{
"name": "logging.level.values",
"values": [
{
"value": "trace"
},
{
"value": "debug"
},
{
"value": "info"
},
{
"value": "warn"
},
{
"value": "error"
},
{
"value": "fatal"
},
{
"value": "off"
}
],
"providers": [
{
"name": "any"
}
]
}
]}
2.2.5. Spring Bean 参照
spring-bean-reference プロバイダーは、現在のプロジェクトの構成で定義されている Bean を自動補完します。このプロバイダーは、次のパラメーターをサポートします。
パラメーター | タイプ | デフォルト値 | 説明 |
---|---|---|---|
|
| なし | 候補者に割り当てられる Bean クラスの完全修飾名。通常、候補ではない Bean を除外するために使用されます。 |
次のメタデータスニペットは、使用する MBeanServer
Bean の名前を定義する標準 spring.jmx.server
プロパティに対応しています。
{"hints": [
{
"name": "spring.jmx.server",
"providers": [
{
"name": "spring-bean-reference",
"parameters": {
"target": "javax.management.MBeanServer"
}
}
]
}
]}
バインダーはメタデータを認識しません。そのヒントを提供する場合、ApplicationContext を使用して Bean 名を実際の Bean 参照に変換する必要があります。 |
3. アノテーションプロセッサーを使用して独自のメタデータを生成する
spring-boot-configuration-processor
jar を使用すると、@ConfigurationProperties
でアノテーションが付けられたアイテムから独自の構成メタデータファイルを簡単に生成できます。jar には、プロジェクトのコンパイル時に呼び出される Java アノテーションプロセッサーが含まれています。
3.1. アノテーションプロセッサーの構成
プロセッサーを使用するには、spring-boot-configuration-processor
への依存関係を含めます。
Maven では、次の例に示すように、依存関係をオプションとして宣言する必要があります。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
次の例に示すように、Gradle では、依存関係を annotationProcessor
構成で宣言する必要があります。
dependencies {
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
}
additional-spring-configuration-metadata.json
ファイルを使用している場合、compileJava
タスクは、次の例に示すように、processResources
タスクに依存するように構成する必要があります。
compileJava.inputs.files(processResources)
この依存関係により、コンパイル中にアノテーションプロセッサーが実行されるときに追加のメタデータが使用可能になります。
プロジェクトで AspectJ を使用している場合は、アノテーションプロセッサーが 1 回だけ実行されることを確認する必要があります。これを行うにはいくつかの方法があります。Maven を使用すると、
|
3.2. 自動メタデータ生成
プロセッサーは、@ConfigurationProperties
でアノテーションが付けられたクラスとメソッドの両方を取得します。
クラスにも @ConstructorBinding
アノテーションが付けられている場合、単一のコンストラクターが予期され、コンストラクターパラメーターごとに 1 つのプロパティが作成されます。それ以外の場合、プロパティは、コレクションおよびマップ型の特別な処理を備えた標準の getter および setter の存在によって検出されます(getter のみが存在する場合でも検出されます)。アノテーションプロセッサーは、@Data
、@Value
、@Getter
、@Setter
lombok アノテーションの使用もサポートしています。
次の例を考えてみましょう。
@ConfigurationProperties(prefix = "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;
これにより、my.server.name
にはデフォルトがなく、my.server.ip
および my.server.port
のデフォルトはそれぞれ "127.0.0.1"
および 9797
の 3 つのプロパティが公開されます。フィールドの Javadoc は、description
属性を設定するために使用されます。たとえば、my.server.ip
の記述は「リッスンする IP アドレス」です。
それらは JSON に追加される前に処理されないため、@ConfigurationProperties フィールドの Javadoc でプレーンテキストのみを使用する必要があります。 |
アノテーションプロセッサーは、いくつかのヒューリスティックを適用して、ソースモデルからデフォルト値を抽出します。デフォルト値は静的に提供する必要があります。特に、別のクラスで定義されている定数を参照しないでください。また、アノテーションプロセッサーは Enum
および Collections
のデフォルト値を自動検出できません。
デフォルト値を検出できなかった場合は、手動のメタデータを提供する必要があります。次の例について考えてみます。
@ConfigurationProperties(prefix = "my.messaging")
public class MyMessagingProperties {
private List<String> addresses = new ArrayList<>(Arrays.asList("a", "b"));
private ContainerType containerType = ContainerType.SIMPLE;
public enum ContainerType {
SIMPLE, DIRECT
}
}
上記のクラスのプロパティのデフォルト値をドキュメント化するには、モジュールの手動メタデータに次のコンテンツを追加できます。
{"properties": [
{
"name": "my.messaging.addresses",
"defaultValue": ["a", "b"]
},
{
"name": "my.messaging.container-type",
"defaultValue": "simple"
}
]}
既存のプロパティの追加のメタデータをドキュメント化するには、プロパティの name のみが必要です。 |
3.2.1. ネストされたプロパティ
アノテーションプロセッサーは自動的に内部クラスをネストされたプロパティと見なします。名前空間のルートで ip
と port
をドキュメント化する代わりに、サブ名前空間を作成できます。更新された例を考えてみましょう:
@ConfigurationProperties(prefix = "my.server")
public class MyServerProperties {
private String name;
private Host host;
public static class Host {
private String ip;
private int port;
}
}
上記の例では、my.server.name
、my.server.host.ip
、my.server.host.port
プロパティのメタデータ情報を生成します。フィールドで @NestedConfigurationProperty
アノテーションを使用して、通常の(非内部)クラスをネストされているかのように扱う必要があることを示すことができます。
これらの型は自動的に識別され、それぞれに対して単一のメタデータプロパティが生成されるため、これはコレクションやマップには影響しません。 |
3.3. メタデータを追加する
Spring Boot の構成ファイルの処理は非常に柔軟であり、@ConfigurationProperties
Bean にバインドされていないプロパティが存在する場合がよくあります。また、既存のキーの一部の属性を調整する必要がある場合があります。このような場合をサポートし、カスタムの「ヒント」を提供できるようにするために、アノテーションプロセッサーは META-INF/additional-spring-configuration-metadata.json
のアイテムをメインメタデータファイルに自動的にマージします。
自動的に検出されたプロパティを参照する場合、説明、デフォルト値、非推奨情報は、指定されていれば上書きされます。手動プロパティ宣言が現在のモジュールで識別されない場合、新しいプロパティとして追加されます。
additional-spring-configuration-metadata.json
ファイルの形式は、通常の spring-configuration-metadata.json
とまったく同じです。追加のプロパティファイルはオプションです。追加のプロパティがない場合は、ファイルを追加しないでください。