25.

【Spring】@Valueアノテーションとは

編集
この記事の要点
  • @Valueプロパティ値 / 環境変数 / SpEL 式を Bean に注入するアノテーション
  • 基本: @Value("\${app.host}")application.properties の値を注入
  • デフォルト値: @Value("\${app.host:localhost}") (プロパティ未定義時の値)
  • SpEL: @Value("#{systemProperties['user.dir']}") で式評価
  • 型変換は自動: String, int, boolean, List, Map, 配列等

 

@Value の基本

application.propertiesapplication.yml に書いた設定値を、Spring 管理 Bean のフィールドに自動注入するアノテーションです。

例: プロパティ注入

# application.properties
app.host=api.example.com
app.port=8080
app.timeout=5000
app.features.enabled=true
app.tags=java,spring,boot
@Service
public class ApiClient {
    @Value("${app.host}")
    private String host;

    @Value("${app.port}")
    private int port;

    @Value("${app.timeout}")
    private long timeout;

    @Value("${app.features.enabled}")
    private boolean enabled;

    @Value("${app.tags}")
    private List tags;  // カンマ区切り自動分割
}

デフォルト値の指定

プロパティが未定義の場合に使う値を : の後に指定:

@Value("${app.host:localhost}")  // app.host が未定義なら "localhost"
private String host;

@Value("${app.port:8080}")  // 数値もOK
private int port;

@Value("${app.timeout:}")  // 空文字
private String timeout;

// プロパティが空 / 未定義の時に null
@Value("${app.optional:#{null}}")  // SpEL の null
private String optional;

SpEL(Spring Expression Language)

単純なプロパティ値だけでなく、式を評価できます。

// システムプロパティ
@Value("#{systemProperties['user.home']}")
private String userHome;

// 環境変数
@Value("#{environment['PATH']}")
private String envPath;

// 他の Bean のフィールド参照
@Value("#{appConfig.maxConnections}")
private int maxConn;

// 計算
@Value("#{2 * 1024}")
private int size;

// 条件式
@Value("#{${app.debug} ? 'DEBUG' : 'PROD'}")
private String mode;

// リスト
@Value("#{T(java.util.Arrays).asList('a', 'b', 'c')}")
private List items;

コンストラクタ注入(推奨)

フィールド注入よりコンストラクタ注入が推奨されます(テスト容易、final 化、循環依存検出):

@Service
public class ApiClient {
    private final String host;
    private final int port;

    public ApiClient(
        @Value("${app.host}") String host,
        @Value("${app.port}") int port
    ) {
        this.host = host;
        this.port = port;
    }
}

複雑な設定は @ConfigurationProperties を使う

関連するプロパティをまとめて受け取るなら @ConfigurationProperties の方が優れます:

// application.yml
app:
  api:
    host: api.example.com
    port: 8080
    timeout: 5000
    retry:
      max-attempts: 3
      delay: 1000
@Component
@ConfigurationProperties(prefix = "app.api")
public class ApiProperties {
    private String host;
    private int port;
    private long timeout;
    private Retry retry = new Retry();

    public static class Retry {
        private int maxAttempts;
        private long delay;
        // getters/setters
    }
    // getters/setters
}

メリット:

  • 型安全 + ネスト構造をそのまま受け取れる
  • バリデーション (@Validated + Bean Validation)
  • IDE 補完が効く(メタデータ自動生成)

プロパティの優先順位

Spring Boot で同名プロパティが複数ソースにある場合の優先順位(高い順):

  1. コマンドライン引数 (--app.host=...)
  2. OS 環境変数 (APP_HOST=...)
  3. application-{profile}.properties
  4. application.properties
  5. @PropertySource で読み込んだ外部ファイル
  6. デフォルトプロパティ

よくあるトラブル

Q. プロパティが注入されず null になる

  • クラスが Bean になっていない(@Service 等が未付与)
  • new でインスタンス化している(Spring 経由でないと注入されない)
  • プロパティキーのタイポ(app.host vs app.hosts
  • YAML のインデントミス

Q. IllegalArgumentException: Could not resolve placeholder

指定したプロパティが見つかりません。デフォルト値(${key:default})を付けるか、プロパティを定義してください。

Q. 型変換エラー(NumberFormatException)

例: @Value("${app.port}") で int 型に注入しようとして文字列が "abc"。プロパティの値を確認。

関連記事

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. @After
  2. @Autowired
  3. @Bean
  4. @Before
  5. @Column
  6. @Component
  7. @Configuration
  8. @Controller
  9. @Data
  10. @Entity
  11. @GeneratedValue
  12. @Id
  13. @Modifying
  14. @PathVariable
  15. @PropertySource
  16. @Repository
  17. @RequestBody
  18. @RequestMapping
  19. @ResponseBody
  20. @RestController
  21. @Service
  22. @SpringBootApplication
  23. @Table
  24. @Transactional
  25. @Value