Java Spring Boot 3でWeb Applicationを作成する

code html digital coding web 1076536

Spring Boot 3でWeb Applicationを作成するチュートリアルです。IDEにはIntellij IDEAを、ビルドツールにはGradleを使用します。Hello Worldを作成し、ソースコードを修正した際に自動的にTomcatが再起動される設定も行います。

目次

JDKのインストール

gradleのversion 3.0.4ではJavaのversion 17を想定しています。そのため、JDK のバージョン17をダウンロードしてIDEで利用可能な状態にしおきます。

今回はJDKとしてEclipse Temurin-17を使用します。以下のサイトからインストーラをダウンロードします。

https://adoptium.net/

OpenJDK17U-jdk_x64_mac_hotspot_17.0.5_8.pkg

インストーラを実行します。

以下のディレクトリにインストールされます。

/Library/Java/JavaVirtualMachines/temurin-17.jdk

jenvに追加します。

jenv add /Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home
temurin64-17.0.5 added
 17.0.5 already present, skip installation
 17.0 already present, skip installation
 17.0.5 already present, skip installation

jenvで利用可能なJDKに追加されたことを確認します。

% jenv versions
* system (set by /Users/[user]/.anyenv/envs/jenv/version)
  17.0
  17.0.5
  9.0
  9.0.4
  oracle64-17.0.5
  oracle64-9.0.4
* system (set by /Users/[user]/.anyenv/envs/jenv/version)
  temurin64-17.0.5

Spring Tool Suite 4

Spring Bootを使ったWebアプリケーション開発には以下の2種類があります。

  1. IDE + Sprint Tools 4の組み合わせで使用する
  2. Spring Tool Suite 4(STS)を使用する

STSはSpring Tools 4が組み込まれたEclipseです。今回は1の方法を採用します。具体的にはIntellij IDEAに組み込まれているSpring Initializrを使用します。

PostgreSQLのインストール (Spring Bootを使うだけなら不要)

以降でPostgreSQLが必要になるのでインストールしておきます。

別手順を参照します。

新規Spring Boot Webアプリケーションプロジェクトの作成

LombokはSetter, Getter等の生成の支援ツールです。

以下のように自動的にいくつかのファイルが生成されます。

build.gradleが自動生成されたことを確認

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.0.4'
    id 'io.spring.dependency-management' version '1.1.0'
}

group 'org.example'
version '1.0-SNAPSHOT'

sourceCompatibility = '17'
targetCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'

    //Spring
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

test {
    useJUnitPlatform()
}

HelloApplication (エントリーポイント)が自動生成されたことを確認

HelloApplication.javaはプログラムのエントリーポイントで、main メソッドを持ちます。プロジェクト名Applicationの命名になっています。

package controller;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class HelloApplication {
    public static void main(String[] args) {
        SpringApplication.run(HelloApplication.class, args);
    }
}

HelloControllerを作成する

main.java.com.example.hello配下にHelloControllerを作成します。

package com.example.hello;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String sayHello() {
        return "Hello, world!";
    }
}

プロジェクトの実行

三角ボタンをクリックして実行します。

大量のメッセージが表示されて起動します。

/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home/bin/java -XX:TieredStopAtLevel=1 -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -Dmanagement.endpoints.jmx.exposure.include=* -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=50249:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Users/[user]/IdeaProjects/Hello/build/classes/java/main:/Users/[user]/IdeaProjects/Hello/build/resources/main:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.projectlombok/lombok/1.18.24/13a394eed5c4f9efb2a6d956e2086f1d81e857d9/lombok-1.18.24.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-web/3.0.2/3f6a2cb4cb11bac3611f5a95e234589eb190dd29/spring-boot-starter-web-3.0.2.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-json/3.0.2/11b9a2903af9014696d2576605bb73e8bca6ee19/spring-boot-starter-json-3.0.2.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter/3.0.2/a9426629b5a83ad64fbe4e1d24081cccf4cdab14/spring-boot-starter-3.0.2.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-tomcat/3.0.2/4d50f0cdcb4b8f74221ae823dd77c18290473045/spring-boot-starter-tomcat-3.0.2.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.springframework/spring-webmvc/6.0.4/84ee8a9107480c92186ef8216ba0e1dca6ee1665/spring-webmvc-6.0.4.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.springframework/spring-web/6.0.4/de18e3e75a0e56534d9df5978bd2f43f950e1b4a/spring-web-6.0.4.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.14.1/f24e8cb1437e05149b7a3049ebd6700f42e664b1/jackson-datatype-jsr310-2.14.1.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.module/jackson-module-parameter-names/2.14.1/2e05a86dba3d4b05074b6a313c4d5b7ff844c8dd/jackson-module-parameter-names-2.14.1.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.datatype/jackson-datatype-jdk8/2.14.1/da194197d187bf24a8699514344ebf0abd7c342a/jackson-datatype-jdk8-2.14.1.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-databind/2.14.1/268524b9056cae1211b9f1f52560ef19347f4d17/jackson-databind-2.14.1.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-autoconfigure/3.0.2/42ad589ec930e05a2ed702a4940955ff97b16a8c/spring-boot-autoconfigure-3.0.2.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot/3.0.2/69d2e0a07f7df180a4aacdc47c47a3db656857dc/spring-boot-3.0.2.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter-logging/3.0.2/1c5c71058a0297534d5c5f33a5d125bbbdb6a390/spring-boot-starter-logging-3.0.2.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/jakarta.annotation/jakarta.annotation-api/2.1.1/48b9bda22b091b1f48b13af03fe36db3be6e1ae3/jakarta.annotation-api-2.1.1.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.springframework/spring-core/6.0.4/8e24ad493887023cf5fac93541c72516f8ed9f6a/spring-core-6.0.4.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.yaml/snakeyaml/1.33/2cd0a87ff7df953f810c344bdf2fe3340b954c69/snakeyaml-1.33.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.apache.tomcat.embed/tomcat-embed-websocket/10.1.5/14529cbd593571dc9029272ddc9166b5ef113fc2/tomcat-embed-websocket-10.1.5.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.apache.tomcat.embed/tomcat-embed-core/10.1.5/21417d3ef8189e2af05aae0a765ad9204d7211b5/tomcat-embed-core-10.1.5.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.apache.tomcat.embed/tomcat-embed-el/10.1.5/c125df13af42a0fc0cd342370449b1276181e2a1/tomcat-embed-el-10.1.5.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.springframework/spring-context/6.0.4/4fffcbb7eb4f1e9f1a4c9d3ca60098f7c063fc05/spring-context-6.0.4.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.springframework/spring-aop/6.0.4/c47b65c09a5a6fc41293b6aa981fcbe24a3adcd0/spring-aop-6.0.4.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.springframework/spring-beans/6.0.4/7d903607ecfcdefccd0d48aea8724632479b3e83/spring-beans-6.0.4.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.springframework/spring-expression/6.0.4/a908e6d3c46fcd6b58221d8427bbaf284bbbee0c/spring-expression-6.0.4.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/io.micrometer/micrometer-observation/1.10.3/32cc59dc8b5f00fba9fa88b7139898b0f7905db7/micrometer-observation-1.10.3.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-annotations/2.14.1/2a6ad504d591a7903ffdec76b5b7252819a2d162/jackson-annotations-2.14.1.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-core/2.14.1/7a07bc535ccf0b7f6929c4d0f2ab9b294ef7c4a3/jackson-core-2.14.1.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-classic/1.4.5/28e7dc0b208d6c3f15beefd73976e064b4ecfa9b/logback-classic-1.4.5.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-to-slf4j/2.19.0/30f4812e43172ecca5041da2cb6b965cc4777c19/log4j-to-slf4j-2.19.0.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.slf4j/jul-to-slf4j/2.0.6/c4d348977a83a0bfcf42fd6fd1fee6e7904f1a0c/jul-to-slf4j-2.0.6.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.springframework/spring-jcl/6.0.4/2d6523d00fc40cdb2c2f409113447940d2c872b5/spring-jcl-6.0.4.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/io.micrometer/micrometer-commons/1.10.3/334080a1a6b849d09d3ef96d7b243fc3c16b2e5a/micrometer-commons-1.10.3.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-core/1.4.5/e9bb2ea70f84401314da4300343b0a246c8954da/logback-core-1.4.5.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-api/2.0.6/88c40d8b4f33326f19a7d3c0aaf2c7e8721d4953/slf4j-api-2.0.6.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-api/2.19.0/ea1b37f38c327596b216542bc636cfdc0b8036fa/log4j-api-2.19.0.jar:/Users/[user]/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-devtools/3.0.2/8e74cf503d8f8b66960ecf3780446c5750866aa6/spring-boot-devtools-3.0.2.jar com.example.hello.HelloApplication

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.0.2)

2023-01-26T22:28:30.235+09:00  INFO 91436 --- [  restartedMain] com.example.hello.HelloApplication       : Starting HelloApplication using Java 17.0.5 with PID 91436 (/Users/[user]/IdeaProjects/Hello/build/classes/java/main started by [user] in /Users/[user]/IdeaProjects/Hello)
2023-01-26T22:28:30.242+09:00  INFO 91436 --- [  restartedMain] com.example.hello.HelloApplication       : No active profile set, falling back to 1 default profile: "default"
2023-01-26T22:28:30.295+09:00  INFO 91436 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2023-01-26T22:28:30.295+09:00  INFO 91436 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2023-01-26T22:28:31.297+09:00  INFO 91436 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2023-01-26T22:28:31.306+09:00  INFO 91436 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-01-26T22:28:31.306+09:00  INFO 91436 --- [  restartedMain] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.5]
2023-01-26T22:28:31.361+09:00  INFO 91436 --- [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-01-26T22:28:31.365+09:00  INFO 91436 --- [  restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1066 ms
2023-01-26T22:28:31.743+09:00  INFO 91436 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2023-01-26T22:28:31.769+09:00  INFO 91436 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2023-01-26T22:28:31.781+09:00  INFO 91436 --- [  restartedMain] com.example.hello.HelloApplication       : Started HelloApplication in 1.951 seconds (process running for 3.035)

ブラウザでアクセスしてみます。

http://localhost:8080/hello

正常にメッセージが表示されました。

Tomcatの自動リロードを有効にする

Spring Boot DevToolsによって、ソースコードに修正を加えた場合にTomcatを自動的に再起動することが可能になります。事前に以下の手順で自動再起動を有効にしておきます。

  1. Build project automaticallyにチェックを入れる

Preferences > Build,Execution,Deployment > CompilerのBuild project automaticallyにチェックを入れる

  1. Advanced SettingsのCompiler設定を変更する

Preferences > Advanced SettingsのAllow auto-make to start even if developed application is currently runningにチェックを入れる

上記の手順完了後、アプリケーションを再起動します。

ソースコード修正後のTomcat自動再起動を確認する

sayHelloメソッドのreturnを以下のように変更してみます。

return "こんにちは、Spring Bootの世界へ!";

Intellij IDEAのコーンソールにTomcatが再起動されているメッセージが表示されます。

ブラウザで⌘ Rで再読込します。以下のようにメッセージが変更されていれば自動再起動は正常に動作しています。

よかったらシェアしてね!
目次