こんにちは。ステックアップアカデミー講師のかびらです。現役のITエンジニアであり、かつAFP保持者として、このチャンネルを通して、ITエンジニアとフリーランスに必要な、ITとお金に関する情報を配信しています。
前回に引き続き、今回も「誰もが一度はつまずく、Spring Bootを解説」シリーズの第5回目をお届けします。このシリーズでは、私も含め誰もが共通してつまずきやすいポイントを、Javaのスキルや経験が浅い若手エンジニアでも簡単に理解できるよう、極力難しい用語を使わずに解説しています。今回のテーマは、Spring Bootでよく使用されるアノテーション編のパート3です。
バリューアノテーション
本章では、@Valueアノテーションについて解説します。@Valueアノテーションは、クラスのメンバ変数に設定して利用します。@Valueアノテーションを付与することで、外部のプロパティ、つまり外部パラメータを直接設定できるようになり、その値をJavaクラス内で利用することができます。
上記のイメージの例では、「test-project.value1」というキーで、プロパティ値が設定されており、Javaクラス内のメンバ変数に、引数に「test-project.value1」のキー値を指定した@Valueアノテーションが付与されています。このようにすることによって、プロパティファイルに設定されている「test-project.value1」の値、「value of application.yml」が、Javaクラス内のpropertyValueというメンバ変数に設定されます。このことにより、Javaクラス内でその値を自由に使用できるようになります。
ちなみに、 @Valueアノテーションはデフォルト値を指定することも可能です。@Valueアノテーションの引数に「コロン(:)」で初期値を設定することで、プロパティファイルに該当のキーが設定されていなくても、デフォルト値が使用できるようになります。
プロパティファイルの仕組み
次に、@Valueアノテーションと深い関係がある、Spring Bootのプロパティファイルの仕組みについて解説いたします。
Spring Bootのプロパティファイルは、「application」という名前で作成し、拡張子には「yml」または「properties」のどちらかを指定します。それぞれの拡張子によって、プロパティの設定構造が異なります。「yml」ファイルでは、プロパティ項目の階層を「コロン(:)」と「改行」を用いて表現します。一方、「properties」ファイルでは、プロパティ項目を「ピリオド(.)」を用いて1行で表現します。
どちらの形式を採用するかは、開発者の好みやプロジェクトの方針によります。ただし、どちらのファイル形式を採用しても、Spring Bootの動作は、同じ挙動をします。ちなみに私は、「yml」表記の方が、親階層の冗長な記述がない分、見やすくて好きです。
次に、プロパティファイルの仕組みの補足説明をします。
まず、上記のイメージでは、「application.yml」が3種類存在していることが確認できると思います。通常の「application.yml」、そして「application」に「dev」が付いた「application-dev.yml」、そして最後に「application」に「prod」が付いた「application-prod.yml」の3つです。「application」の後に付与されている単語は、「環境名」を示しています。「dev」は「develop」の略で「開発環境」を示し、「prod」は「product」の略で「本番環境」を示しています。つまり、Spring Bootの仕様では、「application」の後ろに環境を示す単語を付与することで、各環境に応じたプロパティファイルを切り替えて使用することができます。
ここまでの説明で、プロパティファイルを環境別に指定する仕組みを、ご理解いただけたかと思います。次に、実際に動作環境を指定し、アプリケーションを起動する際の挙動について詳しく見ていきましょう。
動作環境を指定する方法はいくつか存在しますが、今回はSTS上でJavaの起動引数を用いた指定方法をお伝えします。STS上でJavaの起動引数を利用して動作環境を指定する場合、プログラム引数の欄に「spring.profiles.active」というキーを用いて環境を示します。ここでは「dev」という開発環境を指定してみましょう。
「dev」と指定してアプリケーションを起動すると、どのような動作が行われるでしょうか。まず、「application-dev.yml」が読み込まれます。その後、共通の「application.yml」も読み込まれます。このため、通常の「application.yml」は、どの動作環境においても共通的に読み込まれる特性を持っています。そのため、環境に依存しない共通的なプロパティは、この「application.yml」に記述しておくことをおすすめします。
ちなみに、「動作環境に依存しない共通のプロパティは、通常の「application.yml」に定義するのが良い」と説明しましたが、もし通常の「application.yml」と環境指定の「application-dev.yml」に同じプロパティが存在した場合、どちらが優先されるのでしょうか?
答えは、環境指定の「dev」の設定値が優先されます。実際、Spring Bootのプロパティファイルの読込みには優先順位が設定されており、先に環境指定のプロパティファイルを読み、次に通常のプロパティファイルが読み込まれます。例として、上記のイメージのように「test-project.value1」というプロパティが両方のファイルに存在する場合、Javaでは「application-dev.yml」の設定値である「value of application-dev.yml」が採用されます。
プロパティファイルの読込みに関する説明は以上です。なお、ここまでの説明の中で「dev」や「prod」といった環境を示す単語を使いましたが、これらの単語は開発者の裁量で自由に定義可能です。
SpringBootアプリケーションアノテーション
アノテーション編の最終章である本章では、@SpringBootApplicationアノテーションにについて解説します。
@SpringBootApplicationアノテーションは、アプリの処理開始クラスに付与されます。上記のイメージでは、Javaの処理開始メソッド「public static void main」を持つクラスに@SpringBootApplicationアノテーションが付与されているのが確認できます。通常、@SpringBootApplicationアノテーションを持つクラスは、Javaクラスの最上位階層に配置されるのですが、その理由は後ほど解説します。
次に、@SpringBootApplicationアノテーションの役割について解説します。
実は、@SpringBootApplicationアノテーションは、@Configurationアノテーション、@ComponentScanアノテーション、そして@EnableAutoConfigurationアノテーションの、3つのアノテーションを組み合わせた合成アノテーションとなっています。そのため、これらの3つのアノテーションの役割を理解することが重要です。@Configurationアノテーションについては前回の投稿で説明しています。主なポイントとして、このアノテーションが付与されたクラスはBeanとして内部メモリに確保されることを覚えておいてください。今回、特に@ComponentScanアノテーションと@EnableAutoConfigurationアノテーションの2つに焦点を当てて解説します。
まず、@ComponentScanアノテーションについて説明します。
@ComponentScanアノテーションは、名前からも推測できるように、コンポーネントをスキャンする機能を持っています。ここで言う「コンポーネント」とは、ステレオタイプアノテーションなどでBeanとして登録されるクラス群を指します。例えば、上記のイメージを参考にしてください。各クラスにステレオタイプアノテーションが付与されています。このような状態でアプリケーションを起動すると、@ComponentScanアノテーションが付与されている「TestProjectApplication」クラスのパッケージ下に存在する、ステレオタイプアノテーションが付与されている全てのクラスがBeanとして登録されます。このことから、ステレオタイプアノテーションはクラスがBeanとしての登録対象であることを示し、その実際の登録作業は@ComponentScanアノテーションによって行われるということがわかります。
次に、@EnableAutoConfigurationアノテーションの解説を行います。
@EnableAutoConfigurationアノテーションの主な目的は、Spring Bootが提供する「自動設定クラス」をアプリの起動時に自動的に読み込むことにあります。それでは、この「自動設定クラス」とは具体的にどのようなものなのでしょうか?アプリを起動する際に利用される「自動設定クラス」は多数の便利な機能を持っています。これらの便利な機能をいくつかご紹介します。
まず、一つ目として「ViewResolver」を挙げます。ViewResolverを使用することで、コントローラークラスが返すView名と、該当するHTMLが自動で関連づけられます。このため、私たち開発者はコントローラークラスでビュー名を指定するだけで良く、背後で行われる複雑な処理はViewResolverが自動的に取り扱ってくれます。
次に、もう一つの便利な機能として「MessageSource」を取り上げます。まだSpring Bootにおけるメッセージ処理の詳細には触れていませんが、MessageSourceを利用することで、message.propertiesファイルに記載されたメッセージをJavaクラス内で直接使用することが可能になります。
このように、Spring Bootの「自動設定クラス」は様々な便利な機能を提供しており、これらを活用することで、効率よくプログラムを構築することができます。
さいごに
今回の記事でアノテーション編の解説を一区切りします。アノテーション編を通して、Spring Bootでよく使用されるアノテーションの役割を、何となくイメージを持てたのではないでしょうか?今回もまた一つ賢くなりましたね!次回の記事もぜひご覧ください。お読みいただき、ありがとうございました!