VS CodeでSpring Boot開発入門:環境構築と使い方

はい、承知いたしました。VS CodeでSpring Boot開発を始めるための環境構築から具体的な使い方まで、約5000語の詳細な記事を作成します。


VS CodeでSpring Boot開発入門:環境構築と使い方

はじめに

今日のソフトウェア開発において、Webアプリケーションやマイクロサービスは不可欠な要素となっています。その中でも、Javaエコシステムにおけるデファクトスタンダードとして君臨しているのが「Spring Boot」です。シンプルで高速なアプリケーション開発を可能にするSpring Bootは、多くの企業や開発者に愛用されています。

一方で、統合開発環境(IDE)としてはEclipseやIntelliJ IDEAが広く知られていますが、近年では軽量かつ高機能なコードエディタとして「Visual Studio Code(VS Code)」が急速にその存在感を増しています。特にJava開発においては、豊富な拡張機能群によりIDEと遜色ない開発体験を提供し、その柔軟性から多くの開発者に選ばれています。

本記事では、この強力な組み合わせである「VS Code」と「Spring Boot」を用いて、初心者でもスムーズにWebアプリケーション開発を始められるよう、環境構築の最初の一歩から、アプリケーションの作成、実行、デバッグ、さらには基本的なデータベース連携やREST APIの開発、テスト、デプロイまでを網羅的に、かつ詳細に解説します。約5000語に及ぶ本記事を通じて、あなたはSpring Boot開発の基礎を確実に習得し、VS Codeを使いこなす力を身につけることができるでしょう。

さあ、最先端のJava開発環境へ飛び込みましょう!


第1章 開発環境の準備:VS CodeとJava開発の土台を築く

Spring Bootアプリケーションを開発するためには、いくつかの基本的なソフトウェアが必要です。ここでは、それぞれの役割とインストール方法を詳しく解説します。

1.1 Java Development Kit (JDK) のインストール

Spring BootはJavaで動作するため、Javaの実行環境と開発ツールを提供するJDK(Java Development Kit)が必須です。

JDKの役割:
* JRE (Java Runtime Environment): Javaアプリケーションを実行するための最小限の環境。
* JVM (Java Virtual Machine): Javaのバイトコードを実行する仮想マシン。
* 開発ツール: javac (Javaコンパイラ)、java (Java実行ツール)、jar (アーカイブツール) など、Javaアプリケーションの開発に必要なツール群。

推奨バージョン:
JavaにはLTS(Long Term Support)版とそうでないバージョンがありますが、安定性と長期的なサポートの観点から、Java 17 (LTS) または Java 21 (LTS) の利用を強く推奨します。Spring BootもこれらのLTS版を公式にサポートしています。

インストール方法:

JDKのディストリビューションはOracle JDKの他にも、Adoptium (旧 AdoptOpenJDK)、Amazon Corretto、Azul Zulu など様々なベンダーから提供されていますが、ここでは広く利用されているオープンソースのAdoptium Temurinを推奨します。

  1. Adoptium Temurinのダウンロード:

    • Adoptium公式サイトにアクセスします。
    • 「Latest LTS Release」のセクションで、ご自身のOS(Windows, macOS, Linux)とアーキテクチャ(x64など)に合ったバージョンのJDK(例: JDK 17 / HotSpot)を選択し、インストーラーをダウンロードします。
  2. インストーラーの実行:

    • ダウンロードしたインストーラーファイルを実行します。
    • ウィザードに従って進めます。特に設定を変更する必要はありませんが、以下の点を確認または設定することをおすすめします。
      • JAVA_HOME 環境変数の設定: インストール時にこのオプションが表示される場合、チェックを入れて有効にしておくことを推奨します。これは、他のツールがJDKのパスを見つけるために使用します。
      • PATH 環境変数の更新: javaコマンドなどをどこからでも実行できるように、PATHにJDKのbinディレクトリが追加されることを確認します。
  3. 環境変数の確認(手動設定が必要な場合):
    インストーラーで自動設定されなかった場合や、既存のJDKと競合する場合などは、手動で環境変数を設定します。

    • Windows:

      1. 「スタート」メニューを右クリックし、「システム」を選択します。
      2. 「システムの詳細設定」をクリックします。
      3. 「環境変数」ボタンをクリックします。
      4. 「システム環境変数」の「新規」をクリックし、変数名にJAVA_HOME、変数値にJDKのインストールパス(例: C:\Program Files\Eclipse Adoptium\jdk-17.0.x.y-hotspot)を設定します。
      5. Path変数を選択し、「編集」をクリックします。
      6. 「新規」をクリックし、%JAVA_HOME%\binを追加します。
      7. すべてのウィンドウで「OK」をクリックして閉じます。
    • macOS / Linux (Bash / Zshの場合):

      1. ターミナルを開き、以下のコマンドで設定ファイルを開きます(お使いのシェルによって異なります)。
        bash
        # Bashの場合
        vi ~/.bash_profile
        # Zshの場合
        vi ~/.zshrc
      2. ファイル末尾に以下の行を追加します。[JDKのインストールパス]はご自身の環境に合わせて変更してください(例: /Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home)。
        bash
        export JAVA_HOME="/Users/[あなたのユーザー名]/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home" # macOSの例
        export PATH="$JAVA_HOME/bin:$PATH"
      3. ファイルを保存して閉じます。
      4. 以下のコマンドを実行して設定を反映します。
        bash
        # Bashの場合
        source ~/.bash_profile
        # Zshの場合
        source ~/.zshrc
  4. インストールと設定の確認:
    コマンドプロンプトまたはターミナルを開き、以下のコマンドを実行します。
    bash
    java -version
    javac -version
    echo %JAVA_HOME% # Windows
    echo $JAVA_HOME # macOS / Linux

    それぞれのコマンドがJDKのバージョンとJAVA_HOMEのパスを正しく表示すれば、インストールは成功です。

1.2 ビルドツール (MavenまたはGradle) のインストール

Spring Bootプロジェクトの管理には、ビルドツールが不可欠です。これらは、プロジェクトの依存関係の管理、コンパイル、テスト、パッケージングなど、開発プロセスを自動化します。

MavenとGradleの比較:
* Maven: XMLベースの設定ファイル(pom.xml)を使用し、規約に基づいた堅牢なビルドプロセスを提供します。歴史が長く、情報も豊富です。
* Gradle: GroovyまたはKotlin DSLベースの設定ファイル(build.gradle)を使用し、より柔軟で表現豊かなビルドスクリプトを作成できます。増分ビルドや並列実行など、高速なビルドが特徴です。

どちらを選んでもSpring Boot開発は可能ですが、本記事ではMavenを主に使用します。MavenはSpring Initializrのデフォルトでもあり、入門者には比較的学習しやすいでしょう。

Mavenのインストール:

  1. Mavenのダウンロード:

    • Apache Maven公式サイトにアクセスします。
    • 「Files」セクションから、最新の安定版のバイナリアーカイブ(例: apache-maven-3.x.x-bin.zip または apache-maven-3.x.x-bin.tar.gz)をダウンロードします。
  2. アーカイブの展開とパスの設定:
    ダウンロードしたファイルを任意の場所に展開します(例: C:\apache-maven-3.x.x (Windows) または /usr/local/apache-maven-3.x.x (macOS/Linux))。

    その後、Mavenのbinディレクトリへのパスを環境変数PATHに追加します。また、M2_HOME(またはMAVEN_HOME)環境変数を設定することが推奨されます。

    • Windows:

      1. JDKの環境変数設定と同様の手順で、「環境変数」を開きます。
      2. 「システム環境変数」の「新規」をクリックし、変数名にM2_HOME、変数値にMavenを展開したパス(例: C:\apache-maven-3.x.x)を設定します。
      3. Path変数を選択し、「編集」をクリックします。
      4. 「新規」をクリックし、%M2_HOME%\binを追加します。
    • macOS / Linux:

      1. JDKの環境変数設定と同様に、.bash_profileまたは.zshrcを開きます。
      2. ファイル末尾に以下の行を追加します。[Mavenの展開パス]はご自身の環境に合わせて変更してください。
        bash
        export M2_HOME="/usr/local/apache-maven-3.x.x" # 例
        export PATH="$M2_HOME/bin:$PATH"
      3. ファイルを保存し、sourceコマンドで設定を反映します。
  3. インストールと設定の確認:
    コマンドプロンプトまたはターミナルを開き、以下のコマンドを実行します。
    bash
    mvn -v

    Mavenのバージョン情報が表示されれば、インストールは成功です。

1.3 Visual Studio Code (VS Code) のインストール

VS Codeは、Microsoftが開発した無料の軽量なコードエディタです。豊富な拡張機能により、様々な言語の開発に対応できます。

  1. VS Codeのダウンロード:

    • VS Code公式サイトにアクセスします。
    • ご自身のOS(Windows, macOS, Linux)に合ったインストーラーをダウンロードします。
  2. インストーラーの実行:
    ダウンロードしたインストーラーファイルを実行し、ウィザードに従ってインストールを進めます。デフォルト設定で問題ありません。

    • Windows版では、インストール時に「PATHへの追加」や「エクスプローラーのコンテキストメニューに『Codeで開く』を追加」などのオプションが表示されますが、これらはチェックを入れて有効にしておくことを強く推奨します。
  3. VS Codeの起動:
    インストールが完了したら、VS Codeを起動します。初期画面が表示されれば準備完了です。

第2章 VS Code拡張機能の導入:Spring Boot開発を快適にする

VS Codeが真価を発揮するのは、豊富な拡張機能によるカスタマイズ性です。Spring Boot開発を効率的に進めるために、必須の拡張機能を導入します。

2.1 Java開発に必要な基本拡張機能

VS CodeでJava開発を行う上で、最低限導入すべき拡張機能群は「Extension Pack for Java」にまとめられています。

  1. Extension Pack for Java のインストール:
    • VS Codeを起動します。
    • 左側のアクティビティバーにある「Extensions(拡張機能)」アイコン(正方形が4つ並んだアイコン)をクリックします。または Ctrl+Shift+X (macOS: Cmd+Shift+X) を押します。
    • 検索バーに「Extension Pack for Java」と入力し、検索結果から「Extension Pack for Java」を選択します(Microsoft社が提供していることを確認してください)。
    • 「Install」ボタンをクリックしてインストールします。

Extension Pack for Java に含まれる主な拡張機能とその役割:
このパックをインストールすると、以下の主要な拡張機能がまとめて導入されます。

  • Language Support for Java™ by Red Hat:
    • Javaのコード補完(IntelliSense)、定義へ移動、参照の検索、リファクタリングなど、IDEの中核機能を提供します。
    • プロジェクト構造の解析、エラーチェック、警告表示など、開発の生産性を向上させます。
  • Debugger for Java:
    • Javaアプリケーションのデバッグ機能を提供します。ブレークポイントの設定、ステップ実行、変数の検査などが行えます。
  • Maven for Java:
    • Mavenプロジェクトの管理機能を提供します。pom.xmlの依存関係の解決、ビルドゴールの実行、プロジェクト構造の認識などを行います。
  • Project Manager for Java:
    • ワークスペース内のJavaプロジェクトを管理し、簡単にプロジェクトの切り替えや新規作成を可能にします。
  • Test Runner for Java:
    • JUnitやTestNGなどのJavaテストフレームワークのテストを実行・デバッグするためのUIと機能を提供します。

これらの拡張機能がインストールされることで、VS CodeはEclipseやIntelliJ IDEAに匹敵するJava開発環境へと変貌します。

2.2 Spring Boot開発に特化した拡張機能

Spring Bootの特性を活かした開発をさらに快適にするために、以下の拡張機能も導入します。

  1. Spring Boot Extension Pack のインストール:
    • 拡張機能ビューで「Spring Boot Extension Pack」と検索し、これも「Microsoft」が提供しているものを選択してインストールします。

Spring Boot Extension Pack に含まれる主な拡張機能とその役割:

  • Spring Boot Tools:
    • application.propertiesapplication.ymlといった設定ファイルのプロパティに対するコード補完と検証を提供します。
    • Springコンポーネント(@Controller, @Serviceなど)のナビゲーションやシンボル検索を強化します。
    • Spring特有のアノテーションに対する情報表示やクイックフィックスを提供します。
  • Spring Boot Dashboard:
    • VS Codeの左側アクティビティバーにSpring Bootのアイコンが追加されます。
    • ワークスペース内のSpring Bootアプリケーションを一覧表示し、クリック一つで起動、停止、再起動、デバッグ実行などが可能になります。開発中に複数のSpring Bootアプリケーションを扱う際に非常に便利です。
  • Spring Initializr Java Support:
    • VS Code内で直接Spring Initializrの機能を利用し、Spring Bootプロジェクトを簡単に作成できるようになります。

2.3 その他の推奨拡張機能 (任意)

開発体験をさらに向上させるために、以下の拡張機能も検討してください。

  • Lombok:
    • Lombokは、Javaコードからボイラープレートコード(ゲッター、セッター、コンストラクタなど)を自動生成することで、コード量を削減するライブラリです。Lombokをプロジェクトで使用する場合、この拡張機能を導入することで、VS CodeがLombokによって生成されるメソッドなどを正しく認識し、エラー表示を抑制し、コード補完を有効にします。
    • インストール後、VS Codeの再起動が推奨されます。
  • GitLens:
    • VS Codeに強力なGit機能を追加します。コードの行ごとに誰がいつ変更したかを表示する「Blame」機能や、リポジトリ履歴の可視化など、Gitを使った開発には必須と言える拡張機能です。
  • Prettier – Code formatter:
    • JavaScript, TypeScript, CSS, HTML, JSON, Markdownなど、様々な言語のコードを自動的にフォーマットします。プロジェクト全体でコードスタイルを統一するのに役立ちます。JavaコードにはJava固有のフォーマッタが適用されますが、他の設定ファイルなどで役立ちます。

これらの拡張機能を導入することで、VS CodeはSpring Boot開発のための非常に強力で快適な環境となります。


第3章 Spring Bootプロジェクトの作成:Hello, World!

環境構築が完了したら、いよいよ最初のSpring Bootプロジェクトを作成します。ここでは、最も一般的な「Spring Initializr」を使ってプロジェクトを生成する方法を2種類紹介します。

3.1 Spring Initializrとは?

Spring Initializrは、Spring Bootプロジェクトを素早く作成するためのWebベースのツールです。プロジェクトのタイプ(Maven/Gradle)、Javaのバージョン、Spring Bootのバージョン、必要な依存関係(Dependencies)などを選択するだけで、すぐに開発を始められるプロジェクトのひな形を生成してくれます。

3.2 方法1:WebブラウザからSpring Initializrを利用する

  1. Spring Initializrへのアクセス:

  2. プロジェクト設定:
    以下の項目を設定します。

    • Project:
      • Maven Project または Gradle Project を選択します。本記事ではMaven Projectを選択します。
    • Language:
      • Java を選択します。
    • Spring Boot:
      • 推奨される安定版(3.x.x)を選択します。通常は「SNAPSHOT」や「M(Milestone)」が付いていない最新版を選びます。
    • Project Metadata:

      • Group: プロジェクトの所有者や組織を表す逆ドメイン形式のID(例: com.example)。
      • Artifact: プロジェクトの成果物名(例: my-first-spring-boot-app)。
      • Name: アプリケーションの表示名。Artifactと同じでも構いません。
      • Description: プロジェクトの説明。
      • Package name: Javaのルートパッケージ名(GroupとArtifactを組み合わせたもの)。
      • Packaging:
        • Jar: 実行可能な単一のJARファイルとしてパッケージングする場合。Spring Bootの一般的な選択肢です。
        • War: 従来のWebアプリケーションサーバー(Tomcatなど)にデプロイする場合。
        • 通常はJarを選択します。
      • Java:
        • インストール済みのJDKバージョンと同じか、それより低いバージョンを選択します。本記事では17を選択します。
    • Dependencies (依存関係):

      • プロジェクトに必要なライブラリを追加します。「Add Dependencies」ボタンをクリックして検索します。
      • 今回は以下の基本的な依存関係を追加します。
        • Spring Web: Webアプリケーション(RESTful APIを含む)開発のためのSpring MVC機能を提供します。内蔵Tomcatサーバーも含まれます。
        • Spring Data JPA: Java Persistence API (JPA) を使用してデータベース操作を行うための機能を提供します。
        • H2 Database: 開発・テスト用のインメモリデータベース。アプリケーションを停止するとデータが消えるため、手軽に利用できます。
        • Lombok: ボイラープレートコード(ゲッター、セッターなど)を自動生成するためのライブラリ。

    設定例:
    | 項目 | 設定値 |
    | :———— | :———————————– |
    | Project | Maven Project |
    | Language | Java |
    | Spring Boot | 3.2.x (LTSに近い最新版) |
    | Group | com.example |
    | Artifact | demo |
    | Name | demo |
    | Description | Demo project for Spring Boot |
    | Package name | com.example.demo |
    | Packaging | Jar |
    | Java | 17 |
    | Dependencies | Spring Web, Spring Data JPA, H2 Database, Lombok |

  3. プロジェクトの生成とダウンロード:

    • 画面下部の「GENERATE」ボタンをクリックします。
    • demo.zipのような名前のZIPファイルがダウンロードされます。
  4. VS Codeでのプロジェクトの展開と開く:

    • ダウンロードしたZIPファイルを任意のディレクトリ(例: C:\dev\spring-projects)に展開します。demoというフォルダが作成されます。
    • VS Codeを起動します。
    • 「File」>「Open Folder…」を選択し、展開したdemoフォルダを開きます。

    VS Codeがプロジェクトを読み込み、右下に「This workspace has Java projects, would you like to import them to setup build paths?」のようなメッセージが表示されることがあります。「Yes」をクリックして、必要な設定をVS Codeに任せます。

3.3 方法2:VS CodeのSpring Initializr拡張機能を利用する

VS Codeに「Spring Initializr Java Support」拡張機能をインストールしている場合、VS Code内で直接プロジェクトを生成できます。

  1. コマンドパレットを開く:

    • VS Codeで Ctrl+Shift+P (macOS: Cmd+Shift+P) を押し、コマンドパレットを開きます。
  2. プロジェクト作成コマンドの実行:

    • コマンドパレットで「Spring: Create Maven Project」または「Spring: Create Gradle Project」と入力し、Maven Projectを選択します。
  3. ウィザードに従って設定:
    VS Codeの画面下部にプロンプトが表示されるので、以下の手順で設定を進めます。

    • Spring Boot Version: 推奨される安定版を選択(例: 3.2.x)。
    • Project Language: Java を選択。
    • Group Id: com.example と入力。
    • Artifact Id: demo と入力。
    • Packaging: Jar を選択。
    • Java Version: 17 を選択。
    • Dependencies: 必要な依存関係を選択します。検索バーに「web」と入力してEnter、「jpa」と入力してEnter、「h2」と入力してEnter、「lombok」と入力してEnter、最後に選択を完了するために何も入力せずに再度Enterを押します。
  4. プロジェクト保存先の指定:

    • プロジェクトを保存するディレクトリを選択します。新しいdemoフォルダがそのディレクトリ内に作成されます。
  5. プロジェクトを開く:

    • プロジェクトが生成されると、「Would you like to open the new project?」というメッセージが表示されます。「Open in new Window」を選択して、新しいVS Codeウィンドウでプロジェクトを開きます。

どちらの方法で作成しても、最終的なプロジェクト構造は同じになります。

3.4 プロジェクト構造の概要

生成されたプロジェクトは、以下のような基本的な構造を持っています。

demo/
├── .mvn/ # Maven Wrapper関連ファイル
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/demo/
│ │ │ └── DemoApplication.java # メインアプリケーションクラス
│ │ └── resources/
│ │ ├── application.properties # アプリケーション設定ファイル
│ │ ├── static/ # 静的ファイル(HTML, CSS, JSなど)
│ │ └── templates/ # テンプレートファイル(Thymeleaf, FreeMarkerなど)
│ └── test/
│ └── java/
│ └── com/example/demo/
│ └── DemoApplicationTests.java # テストクラス
├── .gitignore # Gitの無視リスト
├── mvnw # Maven Wrapperスクリプト (Linux/macOS)
├── mvnw.cmd # Maven Wrapperスクリプト (Windows)
├── pom.xml # Mavenプロジェクト設定ファイル
└── README.md

  • src/main/java: Javaのソースコードが配置される場所。DemoApplication.javaがアプリケーションのエントリーポイントです。
  • src/main/resources: 設定ファイルや静的ファイル、テンプレートファイルなどが配置される場所。
  • src/test/java: テストコードが配置される場所。
  • pom.xml: Mavenの設定ファイルで、プロジェクトのメタデータ、依存関係、ビルド設定などが記述されています。

これで、最初のSpring Bootプロジェクトの準備が整いました。


第4章 Spring Bootアプリケーションの実行とデバッグ

プロジェクトが作成できたら、次はそれを実行し、必要に応じてデバッグする方法を学びます。

4.1 アプリケーションの実行

Spring Bootアプリケーションを実行する方法はいくつかあります。

  1. Spring Boot Dashboardからの実行(最も推奨):

    • VS Codeのアクティビティバー(左側のアイコン列)にあるSpring Bootアイコン(Springのロゴ)をクリックします。
    • Spring Boot Dashboardビューが表示され、ワークスペース内のSpring Bootプロジェクトが一覧表示されます。
    • demoプロジェクトの下にある再生ボタン(Run)アイコンをクリックします。
    • VS CodeのTERMINALパネルにアプリケーションのログが出力され、起動が完了すると「Started DemoApplication in X.XXX seconds (JVM running for Y.YYY)」のようなメッセージが表示されます。
    • デフォルトでは、Spring Bootアプリケーションはポート8080で起動します。Webブラウザを開き、http://localhost:8080にアクセスしてみてください。エラーページが表示されれば成功です(まだREST APIを実装していないため)。
  2. mainメソッドからの実行:

    • src/main/java/com/example/demo/DemoApplication.javaファイルを開きます。
    • mainメソッドの上に表示される「Run」リンクをクリックします。または、ファイル内で右クリックし、「Run Java」を選択します。
    • これもSpring Boot Dashboardからの実行と同様に、TERMINALパネルにログが出力されます。
  3. VS Codeのターミナルからの実行:

    • VS Codeで Ctrl+@ (macOS: Cmd+@) を押して統合ターミナルを開きます。
    • プロジェクトのルートディレクトリ(pom.xmlがあるディレクトリ)にいることを確認します。
    • 以下のMavenコマンドを実行します。
      bash
      mvn spring-boot:run
    • Gradleを使用している場合は、以下のコマンドを実行します。
      bash
      ./gradlew bootRun
    • アプリケーションが起動します。

4.2 アプリケーションの停止

  • Spring Boot Dashboardから停止:
    • Dashboardビューで実行中のdemoプロジェクトの停止ボタン(四角いアイコン)をクリックします。
  • ターミナルから停止:
    • ターミナルで実行している場合は、Ctrl+Cを押します。

4.3 アプリケーションのデバッグ

デバッグは、プログラムの動作をステップバイステップで確認し、変数の値などを検査することで、バグの原因を特定するために不可欠なプロセスです。

  1. ブレークポイントの設定:

    • src/main/java/com/example/demo/DemoApplication.javaファイルを開きます。
    • 例えば、mainメソッドの適当な行の行番号の左側をクリックします。赤い丸が表示され、ブレークポイントが設定されます。
  2. デバッグ実行の開始:

    • Spring Boot Dashboardから: demoプロジェクトの下にあるデバッグボタン(虫のアイコン)をクリックします。
    • mainメソッドから: mainメソッドの上に表示される「Debug」リンクをクリックします。
    • VS CodeのRun and Debugビューから: VS Codeのアクティビティバーにある「Run and Debug」アイコン(再生ボタンに虫が付いたアイコン)をクリックします。左上のドロップダウンで「Spring Boot App」が選択されていることを確認し、緑の再生ボタンをクリックします。
  3. デバッグ操作:

    • デバッグ実行が開始され、設定したブレークポイントに到達すると、プログラムの実行が一時停止します。
    • VS Codeの左側の「Run and Debug」ビューには、現在の変数の値、ウォッチ式、コールスタック、設定されたブレークポイントなどが表示されます。
    • 上部またはエディタの右上に表示されるデバッグコントロールバーを使って、以下の操作を行います。
      • Continue (F5): 次のブレークポイントまで実行を続行します。
      • Step Over (F10): 現在の行を実行し、次の行に進みます(メソッド呼び出しの中には入らない)。
      • Step Into (F11): 現在の行のメソッド呼び出しの中に入ります。
      • Step Out (Shift+F11): 現在のメソッドから抜け出し、呼び出し元の次の行に進みます。
      • Restart (Ctrl+Shift+F5 / Cmd+Shift+F5): アプリケーションを再起動します。
      • Stop (Shift+F5): デバッグセッションを終了します。

デバッグ機能を活用することで、複雑なロジックの問題を効率的に解決できるようになります。


第5章 基本的なREST APIの開発

Spring Bootの主要な用途の一つは、RESTful Webサービスの構築です。ここでは、簡単なTodoリストAPIを例に、REST APIの基本的な開発手順を学びます。

Spring Bootでは、一般的に以下のレイヤー構造でアプリケーションを設計します。

  • Controller層: クライアントからのHTTPリクエストを受け取り、適切なサービス層のメソッドを呼び出し、レスポンスを返します。主に@RestControllerアノテーションを使用します。
  • Service層: ビジネスロジックを実装します。複数のリポジトリを連携させたり、トランザクション管理を行ったりします。主に@Serviceアノテーションを使用します。
  • Repository層: データベースとのデータのやり取りを担当します。JPA (Java Persistence API) を利用して、永続化処理を行います。主に@RepositoryアノテーションとJpaRepositoryを使用します。
  • Entity層 (Model): データベースのテーブルに対応するJavaオブジェクトを定義します。JPAのアノテーション(@Entity, @Idなど)を使用します。

5.1 エンティティ(Model)の作成

データベースのTodoアイテムに対応するJavaクラスを作成します。

  1. src/main/java/com/example/demo ディレクトリ内に Todo.java を作成します。

    “`java
    package com.example.demo;

    import jakarta.persistence.Entity;
    import jakarta.persistence.GeneratedValue;
    import jakarta.persistence.GenerationType;
    import jakarta.persistence.Id;
    import lombok.Data; // Lombokの@Dataアノテーションをインポート
    import lombok.NoArgsConstructor; // Lombokの@NoArgsConstructorアノテーションをインポート
    import lombok.AllArgsConstructor; // Lombokの@AllArgsConstructorアノテーションをインポート

    @Entity // このクラスがデータベースのテーブルに対応するエンティティであることを示す
    @Data // Lombokのアノテーション: ゲッター、セッター、equals, hashCode, toStringを自動生成
    @NoArgsConstructor // Lombokのアノテーション: 引数なしのコンストラクタを自動生成
    @AllArgsConstructor // Lombokのアノテーション: 全てのフィールドを引数に持つコンストラクタを自動生成
    public class Todo {

    @Id // 主キーであることを示す
    @GeneratedValue(strategy = GenerationType.IDENTITY) // IDが自動生成されることを示す (H2などではIDENTITY)
    private Long id;
    private String title;
    private boolean completed; // 完了しているかどうか
    

    }
    “`

5.2 リポジトリ(Repository)の作成

データベース操作を行うためのインターフェースを定義します。Spring Data JPAを利用することで、基本的なCRUD(Create, Read, Update, Delete)操作を記述することなく利用できます。

  1. src/main/java/com/example/demo ディレクトリ内に TodoRepository.java を作成します。

    “`java
    package com.example.demo;

    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;

    @Repository // このインターフェースがデータアクセス層のリポジトリであることを示す
    // JpaRepositoryを継承することで、Todoエンティティに対するCRUD操作メソッドが自動的に提供される
    // <エンティティクラス, エンティティのIDの型>
    public interface TodoRepository extends JpaRepository {
    // ここにカスタムクエリメソッドを定義することも可能(例: List findByCompleted(boolean completed);)
    }
    “`

5.3 サービス(Service)の作成

ビジネスロジックを実装するクラスです。リポジトリ層とコントローラ層の間に位置し、データ操作の複雑さを隠蔽します。

  1. src/main/java/com/example/demo ディレクトリ内に TodoService.java を作成します。

    “`java
    package com.example.demo;

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;

    import java.util.List;
    import java.util.Optional;

    @Service // このクラスがビジネスロジックを提供するサービス層のコンポーネントであることを示す
    public class TodoService {

    private final TodoRepository todoRepository;
    
    // コンストラクタインジェクションによりTodoRepositoryのインスタンスを注入
    public TodoService(TodoRepository todoRepository) {
        this.todoRepository = todoRepository;
    }
    
    // 全てのTodoアイテムを取得
    public List<Todo> getAllTodos() {
        return todoRepository.findAll();
    }
    
    // IDを指定してTodoアイテムを取得
    public Optional<Todo> getTodoById(Long id) {
        return todoRepository.findById(id);
    }
    
    // 新しいTodoアイテムを作成・保存
    public Todo createTodo(Todo todo) {
        return todoRepository.save(todo);
    }
    
    // Todoアイテムを更新
    public Optional<Todo> updateTodo(Long id, Todo updatedTodo) {
        return todoRepository.findById(id).map(todo -> {
            todo.setTitle(updatedTodo.getTitle());
            todo.setCompleted(updatedTodo.isCompleted());
            return todoRepository.save(todo);
        });
    }
    
    // Todoアイテムを削除
    public boolean deleteTodo(Long id) {
        if (todoRepository.existsById(id)) {
            todoRepository.deleteById(id);
            return true;
        }
        return false;
    }
    

    }
    “`

5.4 コントローラ(Controller)の作成

クライアントからのHTTPリクエストを処理し、JSON形式のレスポンスを返すRESTfulコントローラを作成します。

  1. src/main/java/com/example/demo ディレクトリ内に TodoController.java を作成します。

    “`java
    package com.example.demo;

    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.*;

    import java.util.List;
    import java.util.Optional;

    @RestController // このクラスがRESTful Webサービスのエンドポイントであることを示す
    @RequestMapping(“/api/todos”) // このコントローラ内の全てのエンドポイントのベースパスを設定
    public class TodoController {

    private final TodoService todoService;
    
    public TodoController(TodoService todoService) {
        this.todoService = todoService;
    }
    
    // 全てのTodoアイテムを取得 (GET /api/todos)
    @GetMapping
    public List<Todo> getAllTodos() {
        return todoService.getAllTodos();
    }
    
    // IDを指定して単一のTodoアイテムを取得 (GET /api/todos/{id})
    @GetMapping("/{id}")
    public ResponseEntity<Todo> getTodoById(@PathVariable Long id) {
        Optional<Todo> todo = todoService.getTodoById(id);
        // Optionalが空でなければTodoオブジェクトを200 OKステータスで返す
        // 空であれば404 Not Foundステータスを返す
        return todo.map(ResponseEntity::ok)
                   .orElseGet(() -> ResponseEntity.notFound().build());
    }
    
    // 新しいTodoアイテムを作成 (POST /api/todos)
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED) // 作成成功時に201 Createdステータスを返す
    public Todo createTodo(@RequestBody Todo todo) { // リクエストボディからTodoオブジェクトをマッピング
        return todoService.createTodo(todo);
    }
    
    // Todoアイテムを更新 (PUT /api/todos/{id})
    @PutMapping("/{id}")
    public ResponseEntity<Todo> updateTodo(@PathVariable Long id, @RequestBody Todo todoDetails) {
        Optional<Todo> updatedTodo = todoService.updateTodo(id, todoDetails);
        return updatedTodo.map(ResponseEntity::ok)
                           .orElseGet(() -> ResponseEntity.notFound().build());
    }
    
    // Todoアイテムを削除 (DELETE /api/todos/{id})
    @DeleteMapping("/{id}")
    @ResponseStatus(HttpStatus.NO_CONTENT) // 削除成功時に204 No Contentステータスを返す
    public ResponseEntity<Void> deleteTodo(@PathVariable Long id) {
        if (todoService.deleteTodo(id)) {
            return ResponseEntity.noContent().build();
        } else {
            return ResponseEntity.notFound().build();
        }
    }
    

    }
    “`

5.5 データベース設定の追加 (application.properties)

H2データベースを有効にし、H2コンソールをブラウザからアクセスできるように設定します。

  1. src/main/resources/application.properties ファイルを開き、以下の行を追加します。

    “`properties

    H2 Database Settings

    spring.h2.console.enabled=true # H2コンソールを有効にする
    spring.h2.console.path=/h2-console # H2コンソールのURLパス
    spring.datasource.url=jdbc:h2:mem:testdb # インメモリデータベースを使用
    spring.datasource.driverClassName=org.h2.Driver
    spring.datasource.username=sa
    spring.datasource.password=

    JPA Settings

    spring.jpa.database-platform=org.hibernate.dialect.H2Dialect # H2データベースの方言を指定
    spring.jpa.hibernate.ddl-auto=update # エンティティに基づいてデータベーススキーマを自動更新

    update: 起動時に既存のテーブルを更新(開発時に便利)

    create: 起動時にテーブルを毎回作成し直す(データが失われる)

    create-drop: 起動時に作成し、終了時に削除

    none: 何もしない (本番環境など)

    spring.jpa.show-sql=true # 実行されるSQLログを表示
    spring.jpa.properties.hibernate.format_sql=true # SQLログを整形して表示
    “`

5.6 アプリケーションの実行とAPIのテスト

コードが完成したら、アプリケーションを再起動し、PostmanなどのツールやcURLコマンドを使ってAPIをテストします。

  1. Spring Bootアプリケーションを再起動します。
    Spring Boot Dashboardで再起動ボタンをクリックするか、ターミナルで一度停止してから再度起動します。

  2. H2コンソールにアクセスし、テーブルを確認します。

    • ブラウザで http://localhost:8080/h2-console にアクセスします。
    • JDBC URLが jdbc:h2:mem:testdb になっていることを確認し、「Connect」をクリックします。
    • 左側のナビゲーションツリーにTODOテーブルが表示されているはずです。SELECT * FROM TODO;を実行して内容を確認できます(最初は空です)。
  3. PostmanまたはcURLでAPIをテストします。

    • 全てのTodoを取得 (GET):

      • URL: http://localhost:8080/api/todos
      • Method: GET
      • 結果: [] (最初は空の配列)
    • 新しいTodoを作成 (POST):

      • URL: http://localhost:8080/api/todos
      • Method: POST
      • Headers: Content-Type: application/json
      • Body (raw, JSON):
        json
        {
        "title": "牛乳を買う",
        "completed": false
        }
      • 結果: {"id":1,"title":"牛乳を買う","completed":false} (IDが自動生成される)

      • もう一つ作成してみましょう:
        json
        {
        "title": "記事を執筆する",
        "completed": false
        }

        結果: {"id":2,"title":"記事を執筆する","completed":false}

    • 全てのTodoを再度取得 (GET):

      • URL: http://8080/api/todos
      • Method: GET
      • 結果:
        json
        [
        {"id":1,"title":"牛乳を買う","completed":false},
        {"id":2,"title":"記事を執筆する","completed":false}
        ]
    • 特定のTodoを取得 (GET by ID):

      • URL: http://localhost:8080/api/todos/1
      • Method: GET
      • 結果: {"id":1,"title":"牛乳を買う","completed":false}
    • Todoを更新 (PUT):

      • URL: http://localhost:8080/api/todos/1
      • Method: PUT
      • Headers: Content-Type: application/json
      • Body (raw, JSON):
        json
        {
        "id": 1,
        "title": "牛乳とパンを買う",
        "completed": true
        }
      • 結果: {"id":1,"title":"牛乳とパンを買う","completed":true}
    • Todoを削除 (DELETE):

      • URL: http://localhost:8080/api/todos/2
      • Method: DELETE
      • 結果: HTTPステータス 204 No Content (ボディは空)

これで基本的なREST APIの開発とテストが完了しました。


第6章 テストの記述と実行

ソフトウェア開発において、テストは品質を保証し、リファクタリングを安全に行うために不可欠です。Spring BootプロジェクトはJUnit 5とSpring Boot Testスターターをデフォルトで含んでおり、簡単にテストを記述・実行できます。

6.1 テストの種類

  • ユニットテスト (Unit Test): アプリケーションの個々のコンポーネント(メソッド、クラスなど)が正しく動作するかを検証します。外部システム(データベース、外部APIなど)への依存はモック化(模擬オブジェクトに置き換えること)します。
  • 統合テスト (Integration Test): 複数のコンポーネント(コントローラ、サービス、リポジトリ、データベースなど)が連携して正しく動作するかを検証します。通常は、アプリケーションの一部または全体を起動してテストします。

6.2 ユニットテストの記述例 (TodoService)

TodoServiceのビジネスロジックをテストします。TodoRepositoryはモック化します。

  1. src/test/java/com/example/demo ディレクトリ内に TodoServiceTest.java を作成します。

    “`java
    package com.example.demo;

    import org.junit.jupiter.api.BeforeEach;
    import org.junit.jupiter.api.Test;
    import org.junit.jupiter.api.extension.ExtendWith;
    import org.mockito.InjectMocks;
    import org.mockito.Mock;
    import org.mockito.junit.jupiter.MockitoExtension;

    import java.util.Arrays;
    import java.util.List;
    import java.util.Optional;

    import static org.junit.jupiter.api.Assertions.; // テストアサートのための静的インポート
    import static org.mockito.Mockito.
    ; // Mockitoのための静的インポート

    @ExtendWith(MockitoExtension.class) // MockitoのJUnit 5拡張を有効にする
    public class TodoServiceTest {

    @Mock // TodoRepositoryのモックを作成
    private TodoRepository todoRepository;
    
    @InjectMocks // todoRepositoryモックをTodoServiceに注入
    private TodoService todoService;
    
    private Todo todo1;
    private Todo todo2;
    
    // 各テストメソッドの前に実行される初期化処理
    @BeforeEach
    void setUp() {
        todo1 = new Todo(1L, "牛乳を買う", false);
        todo2 = new Todo(2L, "記事を執筆する", true);
    }
    
    @Test // このメソッドがテストメソッドであることを示す
    void getAllTodos_shouldReturnAllTodos() {
        // モックの振る舞いを定義: todoRepository.findAll()が呼ばれたらtodo1とtodo2のリストを返す
        when(todoRepository.findAll()).thenReturn(Arrays.asList(todo1, todo2));
    
        List<Todo> todos = todoService.getAllTodos();
    
        // 結果の検証
        assertNotNull(todos);
        assertEquals(2, todos.size());
        assertEquals("牛乳を買う", todos.get(0).getTitle());
        assertEquals("記事を執筆する", todos.get(1).getTitle());
        verify(todoRepository, times(1)).findAll(); // findAll()が1回呼ばれたことを検証
    }
    
    @Test
    void getTodoById_shouldReturnTodo_whenFound() {
        // モックの振る舞いを定義: findById(1L)が呼ばれたらOptional.of(todo1)を返す
        when(todoRepository.findById(1L)).thenReturn(Optional.of(todo1));
    
        Optional<Todo> result = todoService.getTodoById(1L);
    
        assertTrue(result.isPresent()); // 結果が存在することを確認
        assertEquals("牛乳を買う", result.get().getTitle());
        verify(todoRepository, times(1)).findById(1L);
    }
    
    @Test
    void getTodoById_shouldReturnEmpty_whenNotFound() {
        // モックの振る舞いを定義: findById(3L)が呼ばれたらOptional.empty()を返す
        when(todoRepository.findById(3L)).thenReturn(Optional.empty());
    
        Optional<Todo> result = todoService.getTodoById(3L);
    
        assertFalse(result.isPresent()); // 結果が存在しないことを確認
        verify(todoRepository, times(1)).findById(3L);
    }
    
    @Test
    void createTodo_shouldSaveAndReturnTodo() {
        Todo newTodo = new Todo(null, "新しいタスク", false); // IDは自動生成される想定でnull
        // モックの振る舞いを定義: save()が呼ばれたら引数をそのまま返す(実際の保存を模倣)
        when(todoRepository.save(any(Todo.class))).thenReturn(todo1);
    
        Todo created = todoService.createTodo(newTodo);
    
        assertNotNull(created);
        assertEquals("牛乳を買う", created.getTitle()); // モックが返したtodo1の内容
        verify(todoRepository, times(1)).save(newTodo);
    }
    
    // ... updateTodo, deleteTodo のテストも同様に記述 ...
    

    }
    “`

6.3 統合テストの記述例 (TodoController)

TodoControllerのエンドポイントが期待通りに動作するかをテストします。Spring Bootのテスト機能を利用し、実際のアプリケーションコンテキストをロードします。

  1. src/test/java/com/example/demo ディレクトリ内に TodoControllerTest.java を作成します。

    “`java
    package com.example.demo;

    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.http.MediaType;
    import org.springframework.test.web.servlet.MockMvc;

    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
    ;
    import static org.hamcrest.Matchers.*;

    @SpringBootTest // Spring Bootアプリケーション全体をロードしてテスト
    @AutoConfigureMockMvc // MockMvcを自動設定
    public class TodoControllerTest {

    @Autowired
    private MockMvc mockMvc; // HTTPリクエストをシミュレートするためのオブジェクト
    
    @Autowired
    private TodoRepository todoRepository; // データベース操作のためにRepositoryも注入(テストデータ準備用)
    
    @Autowired
    private ObjectMapper objectMapper; // JSONとのマッピング用
    
    // 各テストメソッドの前にデータベースをクリーンアップ
    @org.junit.jupiter.api.BeforeEach
    void setup() {
        todoRepository.deleteAll(); // テスト前にデータをクリア
    }
    
    @Test
    void createTodo_shouldReturnCreatedTodo() throws Exception {
        Todo newTodo = new Todo(null, "テストTodo", false);
    
        mockMvc.perform(post("/api/todos") // POSTリクエストをシミュレート
                        .contentType(MediaType.APPLICATION_JSON) // リクエストのContent-Typeを設定
                        .content(objectMapper.writeValueAsString(newTodo))) // リクエストボディをJSON形式で設定
                .andExpect(status().isCreated()) // HTTPステータスが201 Createdであることを期待
                .andExpect(jsonPath("$.title", is("テストTodo"))) // JSONレスポンスのtitleが"テストTodo"であることを期待
                .andExpect(jsonPath("$.completed", is(false))); // JSONレスポンスのcompletedがfalseであることを期待
    }
    
    @Test
    void getAllTodos_shouldReturnEmptyList() throws Exception {
        mockMvc.perform(get("/api/todos")) // GETリクエストをシミュレート
                .andExpect(status().isOk()) // HTTPステータスが200 OKであることを期待
                .andExpect(jsonPath("$", hasSize(0))); // JSONレスポンスが空の配列であることを期待
    }
    
    @Test
    void getAllTodos_shouldReturnTodos() throws Exception {
        todoRepository.save(new Todo(null, "Todo 1", false));
        todoRepository.save(new Todo(null, "Todo 2", true));
    
        mockMvc.perform(get("/api/todos"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$", hasSize(2)))
                .andExpect(jsonPath("$[0].title", is("Todo 1")))
                .andExpect(jsonPath("$[1].title", is("Todo 2")));
    }
    
    @Test
    void getTodoById_shouldReturnTodo_whenFound() throws Exception {
        Todo savedTodo = todoRepository.save(new Todo(null, "Find Me", false));
    
        mockMvc.perform(get("/api/todos/{id}", savedTodo.getId()))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.title", is("Find Me")));
    }
    
    @Test
    void getTodoById_shouldReturnNotFound_whenNotFound() throws Exception {
        mockMvc.perform(get("/api/todos/{id}", 999L)) // 存在しないID
                .andExpect(status().isNotFound()); // 404 Not Foundを期待
    }
    
    // ... updateTodo, deleteTodo のテストも同様に記述 ...
    

    }
    “`

6.4 VS Codeでのテスト実行

VS CodeにはJavaテストのための専用UIが用意されています。

  1. テストビューを開く:

    • VS Codeのアクティビティバーにある「Test Explorer」アイコン(フラスコのアイコン)をクリックします。
    • または Ctrl+Shift+P でコマンドパレットを開き、「Java: Focus on Test Explorer」と入力して実行します。
  2. テストの実行:

    • Test Explorerビューには、プロジェクト内のテストクラスやテストメソッドがツリー形式で表示されます。
    • 全てのテストを実行: ツリーの一番上にある再生ボタンをクリックします。
    • 特定のクラスのテストを実行: テストクラス名の横にある再生ボタンをクリックします。
    • 特定のメソッドのテストを実行: テストメソッド名の横にある再生ボタンをクリックします。
    • 実行結果は、各テストの横に緑のチェックマーク(成功)または赤いXマーク(失敗)で表示されます。失敗したテストをクリックすると、エディタでそのテストメソッドにジャンプし、問題の詳細を確認できます。

テストを定期的に実行することで、コードの変更が既存の機能に悪影響を与えないことを確認し、品質の高いアプリケーションを開発することができます。


第7章 ビルドとデプロイ

開発したSpring Bootアプリケーションは、最終的に実行可能なパッケージとしてビルドされ、サーバーにデプロイされます。

7.1 実行可能JARファイルのビルド

Spring Bootアプリケーションは、内蔵のWebサーバー(Tomcatなど)を含んだ単一の「実行可能JAR(Fat JARまたはUber JAR)」ファイルとしてパッケージングされるのが一般的です。これにより、特別なアプリケーションサーバーなしで、Javaがインストールされている環境であればどこでも実行できます。

  1. VS Codeの統合ターミナルを開きます。

    • Ctrl+@ (macOS: Cmd+@) を押します。
  2. Mavenコマンドを実行してビルドします。

    • プロジェクトのルートディレクトリ(pom.xmlがある場所)に移動していることを確認します。
    • 以下のコマンドを実行します。
      bash
      mvn clean install
    • clean: 以前のビルドで生成されたファイルを削除します。
    • install: プロジェクトをコンパイル、テスト、パッケージング(JARファイルの作成)し、その成果物をローカルのMavenリポジトリにインストールします。
    • ビルドが成功すると、BUILD SUCCESSというメッセージが表示されます。
  3. JARファイルの確認:

    • プロジェクトのルートディレクトリにtargetという新しいディレクトリが作成されます。
    • targetディレクトリ内に、demo-0.0.1-SNAPSHOT.jarのような名前の実行可能JARファイルが生成されているはずです。

7.2 JARファイルの実行

生成されたJARファイルは、JDKがインストールされている任意の環境で簡単に実行できます。

  1. ターミナルでJARファイルがあるディレクトリ(targetディレクトリ)に移動します。
    bash
    cd target

  2. 以下のコマンドを実行します。
    bash
    java -jar demo-0.0.1-SNAPSHOT.jar

    • アプリケーションが起動し、コンソールにログが出力されます。
    • Webブラウザで http://localhost:8080/api/todos にアクセスし、APIが動作することを確認できます。

7.3 Dockerを利用したデプロイ(概念と簡単な例)

今日のクラウドネイティブな環境では、Dockerコンテナとしてアプリケーションをパッケージングし、デプロイすることが一般的です。これにより、開発環境と本番環境の差異をなくし、より一貫性のあるデプロイが可能になります。

Dockerfileの作成例:

プロジェクトのルートディレクトリにDockerfileという名前のファイルを作成します。

“`dockerfile

ベースイメージとしてAdoptium Temurinの軽量なJREイメージを使用

FROM eclipse-temurin:17-jre-focal

JARファイルの名前を環境変数として定義

ARG JAR_FILE=target/*.jar

ホストからコンテナの/appディレクトリにJARファイルをコピー

COPY ${JAR_FILE} app.jar

コンテナがリッスンするポートを公開

EXPOSE 8080

コンテナ起動時に実行されるコマンド

ENTRYPOINT [“java”,”-jar”,”/app.jar”]
“`

Dockerイメージのビルドと実行:

  1. Docker Desktopがインストールされ、実行されていることを確認します。
  2. VS Codeの統合ターミナルで、プロジェクトのルートディレクトリにいることを確認します。
  3. Dockerイメージをビルドします。
    bash
    docker build -t spring-boot-demo .

    • -t spring-boot-demo: イメージにspring-boot-demoというタグ(名前)を付けます。
    • .: Dockerfileが現在のディレクトリにあることを示します。
  4. Dockerコンテナを実行します。
    bash
    docker run -p 8080:8080 spring-boot-demo

    • -p 8080:8080: ホストのポート8080をコンテナのポート8080にマッピングします。これにより、ホストマシンからlocalhost:8080でコンテナ内のアプリケーションにアクセスできるようになります。
    • spring-boot-demo: 実行するイメージの名前。

これで、Spring BootアプリケーションがDockerコンテナ内で実行され、ホストマシンからアクセスできるようになります。クラウド環境へのデプロイも、このDockerイメージを各種コンテナサービス(AWS ECS, Azure Container Apps, Google Cloud Runなど)にプッシュする形で行われます。


第8章 さらに踏み込んだ開発とVS Codeの活用

ここまででSpring Boot開発の基本的な流れを学びましたが、さらに開発を効率化し、アプリケーションを堅牢にするためのテクニックとVS Codeの便利な機能を紹介します。

8.1 Lombokの活用

第5章でTodoエンティティにLombokのアノテーション(@Data, @NoArgsConstructor, @AllArgsConstructor)を適用しました。Lombokは、ゲッター、セッター、コンストラクタ、equals(), hashCode(), toString()などの定型的なコードを自動生成することで、コード量を劇的に削減し、可読性を向上させます。

Lombokの導入(pom.xml):

プロジェクト作成時にLombokを選択していれば既に含まれていますが、手動で追加する場合はpom.xml<dependencies>セクションに以下を追加します。

xml
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

VS CodeでのLombokサポート:

Lombokはコンパイル時にコードを生成するため、VS Codeがそれらの生成されたメソッドを認識できるように、前述の「Lombok」拡張機能のインストールを忘れないでください。

8.2 Spring Boot Actuatorによるモニタリング

Spring Boot Actuatorは、本番環境でアプリケーションを監視、管理するためのエンドポイントを提供します。アプリケーションの健全性、メトリクス、環境設定、スレッドダンプなど、様々な情報を取得できます。

Actuatorの導入(pom.xml):

xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

設定 (application.properties):

デフォルトでは限られたエンドポイントしか公開されていません。全ての公開されているエンドポイントをHTTP経由で利用可能にするには、以下を設定します。

properties
management.endpoints.web.exposure.include=*

Actuatorエンドポイントの利用:

アプリケーションを再起動した後、以下のURLにアクセスして情報を確認できます。

  • http://localhost:8080/actuator:利用可能な全てのエンドポイントのリスト
  • http://localhost:8080/actuator/health:アプリケーションの健全性情報
  • http://localhost:8080/actuator/info:カスタム情報(application.propertiesinfo.*で設定可能)
  • http://localhost:8080/actuator/metrics:様々なメトリクス情報
  • http://localhost:8080/actuator/env:環境変数と設定プロパティ

8.3 プロファイル (Profiles) の活用

Spring Bootのプロファイル機能を使用すると、異なる環境(開発、テスト、本番など)に応じて異なる設定を適用できます。

  1. プロファイル固有の設定ファイルを作成:

    • src/main/resources ディレクトリに、例えば application-dev.properties (開発環境用) と application-prod.properties (本番環境用) を作成します。

    • application-dev.properties (例: H2 DBを開発用に設定)
      properties
      spring.datasource.url=jdbc:h2:file:./devdb # ファイルベースのH2 DB
      spring.h2.console.enabled=true

    • application-prod.properties (例: PostgreSQLを本番用に設定)
      properties
      spring.datasource.url=jdbc:postgresql://your_db_host:5432/your_db_name
      spring.datasource.username=your_prod_user
      spring.datasource.password=your_prod_password
      spring.jpa.hibernate.ddl-auto=none # 本番では自動DDLは無効化が推奨
      spring.h2.console.enabled=false # 本番ではH2コンソールを無効化
  2. プロファイルをアクティブにする方法:

    • application.propertiesでデフォルトを設定:
      properties
      spring.profiles.active=dev
    • コマンドライン引数で指定:
      bash
      java -jar demo.jar --spring.profiles.active=prod
    • 環境変数で指定:
      bash
      export SPRING_PROFILES_ACTIVE=prod
      java -jar demo.jar

これにより、環境ごとの設定管理が容易になります。

8.4 VS Codeの便利な機能とショートカット

VS Codeを最大限に活用するために、いくつかの便利な機能とショートカットを覚えておきましょう。

  • コマンドパレット (Ctrl+Shift+P / Cmd+Shift+P): VS Codeのあらゆる機能にアクセスできる最も重要な入り口です。何かをしたいと思ったら、まずここから検索してみましょう。
  • ファイルを開く (Ctrl+P / Cmd+P): ファイル名をタイプするだけで素早くファイルを開けます。
  • サイドバーの切り替え (Ctrl+B / Cmd+B): エディタ領域を広く使いたいときにサイドバーを隠したり表示したりできます。
  • 統合ターミナル (Ctrl+@ / Cmd+@): VS Code内で直接コマンドを実行できます。複数のターミナルを開くことも可能です。
  • 行コメントアウト (Ctrl+/ / Cmd+/): 選択した行、またはカーソルがある行をコメントアウト/アンコメントします。
  • 複数カーソル:
    • Altを押しながらクリックしていくと、複数の場所にカーソルを配置できます。
    • Ctrl+D (macOS: Cmd+D) で、選択範囲と同じ単語を次々に選択し、一括で編集できます。
  • コードスニペット: 繰り返し使うコードパターンを素早く挿入できます。例えばforと入力してTabキーを押すとforループのひな形が展開されるなど。Java拡張機能には多くのスニペットが含まれています。
  • Git統合: 左側のアクティビティバーにある「Source Control」アイコン (Ctrl+Shift+G / Cmd+Shift+G) から、ファイルの変更の追跡、コミット、ブランチの切り替え、マージなど、Gitの基本的な操作をVS Code内で直接行えます。GitLens拡張機能と組み合わせるとさらに強力になります。
  • Peek Definition (Alt+F12 / Option+F12): メソッドやクラスの定義元を、現在のエディタを離れることなくポップアップで表示します。
  • Go to Definition (F12): メソッドやクラスの定義元に直接ジャンプします。
  • Find All References (Shift+F12): カーソルがある要素が参照されているすべての場所を検索し、一覧表示します。

これらの機能を使いこなすことで、開発効率が格段に向上します。


第9章 トラブルシューティング

開発中には様々な問題に遭遇することがあります。ここでは、Spring BootとVS CodeでのJava開発においてよくある問題とその対処法を紹介します。

9.1 アプリケーションが起動しない/ポートが使用中

  • 症状: アプリケーション起動時に「Port 8080 already in use」のようなエラーが表示される。
  • 原因: 別のアプリケーション(以前起動したSpring Bootアプリ、Tomcat、他のWebサーバーなど)が既に8080番ポートを使用しているためです。
  • 対処法:
    1. ポートを占有しているプロセスを特定し、終了させる:
      • Windows:
        bash
        netstat -ano | findstr :8080
        # 上記で表示されたPID (プロセスID) を使ってプロセスを強制終了
        taskkill /PID [PID] /F
      • macOS/Linux:
        bash
        lsof -i :8080
        # 上記で表示されたPIDを使ってプロセスを強制終了
        kill -9 [PID]
    2. アプリケーションのポートを変更する:
      • src/main/resources/application.propertiesに以下の行を追加し、別のポート(例: 8081)を指定します。
        properties
        server.port=8081

9.2 依存関係の解決エラー

  • 症状: pom.xmlを変更した後やプロジェクトのインポート時に、Cannot resolve symbol '...'Could not find artifact ... のようなエラーが表示される。
  • 原因: Mavenリポジトリから必要な依存関係がダウンロードできていない、またはキャッシュが破損している可能性があります。
  • 対処法:
    1. Maven依存関係を更新する:
      • VS CodeのEXPLORERビューでpom.xmlファイルを右クリックし、「Maven」>「Update project」または「Reload Project」を選択します。
    2. Mavenキャッシュをクリアする:
      • ローカルのMavenリポジトリ (~/.m2/repositoryディレクトリ) の内容が破損している可能性があります。問題の依存関係に関連するフォルダを削除し、再度mvn clean installを実行してみます。
    3. インターネット接続を確認する: 依存関係のダウンロードにはインターネット接続が必要です。
    4. pom.xmlの記述ミスを確認する: グループID、アーティファクトID、バージョンなどが正しいか確認します。

9.3 ClassNotFoundException または NoClassDefFoundError

  • 症状: アプリケーション実行時に、特定のクラスが見つからないというエラーが発生する。
  • 原因: クラスパスにそのクラスが含まれていない(依存関係が正しく解決されていない)、またはクラス名が間違っている。
  • 対処法:
    1. pom.xmlに適切な依存関係が追加されているか確認する。
    2. ビルドツールが正しく実行されているか確認する。 (mvn clean installを再度実行してみる)。
    3. VS CodeのJava Language Serverが正しく動作しているか確認する。 VS Codeを再起動したり、Ctrl+Shift+Pで「Java: Clean Java Language Server Workspace」を実行してみる。

9.4 データベース接続エラー

  • 症状: データベースへの接続に失敗する。
  • 原因: データベースサーバーが起動していない、接続情報(URL, ユーザー名, パスワード)が間違っている、ポートがブロックされているなど。
  • 対処法:
    1. application.propertiesのデータベース接続設定を確認する。 URL、ユーザー名、パスワードが正しいか。
    2. データベースサーバーが起動しているか確認する。 (H2の場合は自動起動されますが、外部DBの場合は手動で起動が必要です)。
    3. ファイアウォールの設定を確認する。 データベースのポートがブロックされていないか。
    4. spring.jpa.hibernate.ddl-autoの設定を確認する。 特に本番環境ではupdatecreateではなくnoneに設定すべきです。

9.5 デバッグが機能しない

  • 症状: ブレークポイントが無視される、デバッグ情報が表示されない。
  • 原因: デバッガが正しくアタッチされていない、デバッグ情報を持つようにコンパイルされていない。
  • 対処法:
    1. VS CodeのJava Debugger拡張機能がインストールされているか確認する。
    2. デバッグモードで起動しているか確認する。 Runボタンではなく、DebugボタンやF5キーで起動しているか。
    3. pom.xmlにデバッグに必要な設定が含まれているか確認する。 (通常はSpring Bootのデフォルト設定で問題ありません)。
    4. VS Codeの再起動やワークスペースのクリーンアップを試す。

9.6 エラーログの確認

どのような問題に遭遇しても、まずはアプリケーションのログを注意深く確認することが最も重要です。VS CodeのTERMINALパネルや、アプリケーションが出力するログファイル(logging.file.nameプロパティで設定可能)には、エラーの原因を示唆する情報が含まれています。スタックトレースを読み解く練習をしましょう。


結論

本記事では、VS CodeとSpring Bootを組み合わせたJava開発の基礎を、環境構築からREST APIの開発、テスト、ビルド、デプロイ、そしてトラブルシューティングまで、網羅的かつ詳細に解説しました。

あなたは、以下の重要なスキルと知識を習得しました。

  • Java JDK、Maven、VS Codeのインストールと設定
  • Spring Boot開発に必須のVS Code拡張機能の導入
  • Spring Initializrを使用したSpring Bootプロジェクトの作成方法
  • VS Code内でのSpring Bootアプリケーションの実行とデバッグ
  • Controller、Service、Repositoryレイヤーを用いたREST APIの設計と実装
  • H2データベースとの連携
  • ユニットテストと統合テストの記述とVS Codeでの実行
  • 実行可能JARファイルのビルドとDockerによるコンテナ化の基本
  • Lombok、Actuator、プロファイルといった便利なSpring Boot機能の活用
  • 一般的な開発上の問題に対するトラブルシューティング

これらは、現代のJava Webアプリケーション開発における非常に強力な基盤となります。

次のステップ:

本記事で学んだことをさらに深掘りし、より高度な開発に挑戦することで、あなたのスキルは飛躍的に向上するでしょう。

  • データベース: PostgreSQLやMySQLなど、永続的な外部データベースとの連携を試す。
  • 認証・認可: Spring Securityを導入し、アプリケーションにセキュリティ機能を追加する。
  • データ検証: javax.validationjakarta.validation を用いて、入力データのバリデーションを実装する。
  • 非同期処理: @AsyncアノテーションやSpring WebFlux(リアクティブプログラミング)を使って、非同期処理を導入する。
  • メッセージング: RabbitMQやKafkaなどのメッセージキューと連携し、非同期通信を実現する。
  • マイクロサービス: 複数のSpring Bootアプリケーションを連携させ、マイクロサービスアーキテクチャを構築する。
  • フロントエンド連携: ReactやVue.jsなどのJavaScriptフレームワークと連携し、本格的なWebアプリケーションを構築する。

Spring BootとVS Codeの組み合わせは、その柔軟性と生産性から、あなたの開発体験を大きく変えるでしょう。この知識を活かして、素晴らしいアプリケーションを開発してください!

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール