きり丸の技術日記

技術検証したり、資格等をここに残していきます。

SpringのValueに初期値を与える(エラーを起こさずにnullも初期値にする)

小ネタ。@Valueで初期値を与えたい時の記法をメモします。マッピングするプロパティがない場合、BeanCreationExceptionが発生してしまうので、それが発生しないようにします。

環境

  • Java
    • 17
  • SpringBootTest
    • 2.7.4

ゴール

  • SpringのValueで初期値を渡す
  • マッピング先がない場合にExceptionではなくnullを設定する
# 次のExceptionが発生しないようにする
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'kirimaru.config.SpringValueTests': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'app.config.appName2' in value "${app.config.appName2}"

対応

@Value(${placeholder:defaultValue})と記載する。

app.config.appNameにアプリケーション名を設定していた場合、@Value("${app.config.appName:defaultName}")と記載すると設定値を表示します。設定されていない場合はデフォルト値のdefaultNameを表示します。

nullを初期値に渡したい場合は、@Value("${placeholder:#{null}}")として#{null}を渡す必要があります。もし#{}を使用しない場合はnullという文字列が渡ってしまいます。

テスト

次のテストコードで動作確認しました。今回はDIしていることだけを確認したいため、例外が発生することを確認したい場合はSpringBootTestを使用してください。

@SpringJUnitConfig(SpringValueTests.Config.class)
@TestPropertySource(properties = {"app.config.appName=testApplication"})
class SpringValueTests {

  @Value("${app.config.appName:defaultName}")
  private String appName;
  @Value("${app.config.appName2:defaultName}")
  private String appName2;
  @Value("${app.config.appName3:null}")
  private String appName3;
  @Value("${app.config.appName4:#{null}}")
  private String appName4;

  @ComponentScan({"kirimaru.biz.domain.hogehoge"})
  public static class Config {}

  @Test
  void test_01() {
    SoftAssertions softly = new SoftAssertions();

    softly.assertThat(appName).isEqualTo("testApplication");
    softly.assertThat(appName2).isEqualTo("defaultName");
    softly.assertThat(appName3).isEqualTo("null");
    softly.assertThat(appName4).isNull();

    softly.assertAll();
  }
}

ソースコード

終わりに

開発環境ではproxyを経由したいが、本番環境ではproxyを経由したくない。しかし、変な設定値を設定ファイルに残したくない。

そのようなユースケースで使用しました。地味にやり方が分からなかったので、まとめられてよかったです。

類似情報