備忘録っつーか、メモっていうか、チラシの裏。
SpringBootでプロパティを簡単に扱う方法
大きく以下の2つ。
@ConfigurationProperty
を使う(クラスにアノテート)@Value
を使う(フィールドにアノテート)
前者は文字通り、アノテートしたBeanに対してプロパティ経由で(多分PropertyDescriptorか何か使って)データバインドしてくれる。
後者は、Beanのフィールドにアノテートして値を(リフレクションで直接)データバインドしてくれる。
それぞれのメリット・デメリット
前者のメリットはとにかく「楽ちん」であること。
プロパティ(application.properties
)のノードとBeanの構成を合わせてやるだけで良く、Beanの方がネストしたデータ構造を持ってても良いと言うのが便利。
デメリットとして、プロパティ経由でデータバインドしてるので、publicなgetter/setterが必須になると言う事。 つまり、読み取り専用の、イミュータブルなプロパティと言う物を表現出来なくなると言う事。
デメリットと言う程のアレかと言うとまたアレだけど、個人的には大嫌い。
悩みどころ
システムのプロパティをプログラムが動作中に変更するなんて要件は、これはもう99%有り得ないと言って良いので、システムプロパティ(を保持するBean)がイミュータブルに出来ないってのは設計的に物凄くキモチワルイ。
ので ConfigurationProperties
を使うのはなー、なんかなー、ちょっとなー、と思ってる。
でもどうやら圧倒的に推奨されてるのはこっちらしいんだよなぁ、、、何でか解らんけど。
暫定判断
プロジェクトメンバの平均レベルを踏まえて判断すべきだから、最終的な判断はケースバイケースになる。
と言う前提での話として。
今回は少数精鋭と言って良い体制なので、ある程度性善説に基づいて「システムプロパティのsetterを使うようなバカはいねえだろ」と言う前提で @ConfigurationProperties
を使うと言うのもアリと言えばアリか。
気持ちとしては @Value
の方で安全な(イミュータブルな)プロパティを作りたい所だけど、、、
- 一つ一つフィールド単位でアノテートしていくのが面倒。
- Beanが入れ子構造を持った時に上手く表現し難い。
と言う事で、費用対効果というか、労力対効果として微妙かなぁ、、、とも思う。
特に後者がなぁ、、、@Value
バインドする末端のクラスを幾つか作って、それを@Autowired
で纏める外側のConfigクラスを作って、業務実装ではこの外側のConfigを@Autowired
で注入、って言うやり方が良いのだろうか?
ちょっと、この辺のSpringBoot的なベストプラクティスが良く解らん。
参考にしたくてもQiitaやブログに載ってるのは大抵、かなりシンプルな構成で、Beanがフラットで済んでるケースが多くて、多少複雑なBean構造の場合に@Value
をどう使うべきかがちょっと良く解らない。
若しかして、そうなった時点で@Value
と言う選択肢を捨てるべき、って言う事なのかな。
あ、そうそう。
言い忘れてたけど今SpringBootやってるんだよね。(遅)