Your First Spring Boot Application with Spring Initializr
Introduction
This tutorial creates your first Spring Boot application, a small web application that answers HTTP requests, starting from Spring Initializr, the official project generator. We will start with what Spring Initializr is and the options it asks for, and generate a project from the website or from the command line. We will then walk through the generated project - its folders, itspom.xml and its main class - and add a REST controller. Next we will run the application, call it with real HTTP requests, and read its startup log line by line. Lastly, we will run the test that Initializr generates and look at where to go from there.(This tutorial starts the Spring Boot module of the Spring series. If you are new to Spring, What is Spring? Spring Framework vs Spring Boot ExplainedClick to read tutorial: What is Spring? Spring Framework vs Spring Boot Explained explains how Spring Boot relates to the Spring Framework.)
What is Spring Initializr?
Spring Initializr, at start.spring.io, generates the skeleton of a Spring Boot project: a build file with the right dependencies and plugin, a main class, a configuration file, a first test, and a build tool wrapper. You fill in a short form, click Generate, and download a ZIP file that is ready to open in an IDE and run.The same generator is built into IntelliJ IDEA (New Project > Spring Boot), VS Code (the Spring Boot Extension Pack), and Eclipse with the Spring Tools, and it has an HTTP API that tools and scripts can call. Whichever you use, the result is the same project.
The options on start.spring.io
The form asks for a few choices. For this tutorial's application, they are -- Project: the build tool - Maven, Gradle - Groovy or Gradle - Kotlin. This series uses Maven.
- Language: Java, Kotlin or Groovy. We use Java.
- Spring Boot: the Boot version. Initializr pre-selects the latest stable release, which at the time of writing is 4.1.2; versions marked SNAPSHOT or RC are previews and not meant for real projects.
- Project Metadata: Group
com.javabrahman, Artifactfirst-app, a Description, and the Package namecom.javabrahman.firstapp, which Initializr derives from the group and artifact. - Packaging: Jar, the usual choice for Spring Boot, which runs with its own embedded web server. War is for deploying to an external server.
- Java: the Java version - 17, 21, 25 or 27 at the time of writing. Spring Boot 4 needs at least Java 17; this series uses Java 25, the current long-term-support release.
- Dependencies: the features the application needs. We add only Spring Web, for building web applications and REST APIs with Spring MVC.
first-app.zip. The same project can be generated from a terminal through Initializr's HTTP API -
curl https://start.spring.io/starter.zip -d type=maven-project -d bootVersion=4.1.2 -d javaVersion=25 -d groupId=com.javabrahman -d artifactId=first-app -d packageName=com.javabrahman.firstapp -d dependencies=web -o first-app.zip
The generated project
Unzipped, the project looks like this -first-app
|-- .gitattributes
|-- .gitignore
|-- HELP.md links to the documentation of the chosen dependencies
|-- mvnw, mvnw.cmd the Maven wrapper scripts, for Unix and Windows
|-- .mvn/wrapper/ wrapper settings: which Maven version to download
|-- pom.xml the Maven build file
`-- src
|-- main
| |-- java/com/javabrahman/firstapp
| | `-- FirstAppApplication.java the main class
| `-- resources
| |-- application.properties configuration
| |-- static/ static web files (HTML, CSS, JavaScript)
| `-- templates/ server-side templates, if a template engine is added
`-- test/java/com/javabrahman/firstapp
`-- FirstAppApplicationTests.java a first test
mvnw) downloads the right version of Maven the first time it runs, so the project builds on any machine with a JDK, even one without Maven installed. In the commands below, ./mvnw (or mvnw.cmd on Windows) can always replace mvn.
The pom.xml
Here is thepom.xml exactly as Initializr generated it for our choices -
pom.xml generated by Spring Initializr
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.1.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.javabrahman</groupId>
<artifactId>first-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>first-app</name>
<description>My first Spring Boot application</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>25</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Explanation of the pom.xml
- The parent,
spring-boot-starter-parentversion 4.1.2, gives the project Spring Boot's defaults: the versions of hundreds of libraries that are known to work together, compiler settings, resource filtering, and plugin configuration. That is why the dependencies below have no<version>. java.version25 sets the Java version the code is compiled for.spring-boot-starter-webmvcis the starter for the Spring Web dependency. It brings Spring MVC, an embedded Tomcat server and JSON support in one dependency. (In Spring Boot 3 and earlier it was calledspring-boot-starter-web; Spring Boot 4 renamed it.) Starters are covered in detail in Spring Boot Starters ExplainedClick to read tutorial: Spring Boot Starters Explained with Examples.spring-boot-starter-webmvc-test, withtestscope, brings JUnit 5, AssertJ, Mockito and Spring's test support - used only for compiling and running tests, never packaged with the application.- The
spring-boot-maven-pluginadds thespring-boot:rungoal and packages the application as an executable jar, covered in Packaging Spring Boot AppsClick to read tutorial: Packaging Spring Boot Apps: Executable and Layered JARs. - The empty
url,licenses,developersandscmelements are placeholders for project information; they can be filled in or deleted.
The main class
The only Java code Initializr generates is the main class -FirstAppApplication.java generated by Spring Initializr
package com.javabrahman.firstapp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class FirstAppApplication {
public static void main(String[] args) {
SpringApplication.run(FirstAppApplication.class, args);
}
}
@SpringBootApplication marks this as the application's configuration class and switches on three things: component scanning of this class's package and its sub-packages, auto-configuration, and the ability to declare @Bean methods here. SpringApplication.run() starts the application: it creates the application context, applies the auto-configuration, and - because Spring MVC is on the classpath - starts an embedded Tomcat web server. How auto-configuration decides what to set up is explained in How Spring Boot Auto-Configuration WorksClick to read tutorial: How Spring Boot Auto-Configuration Works.The generated
application.properties holds a single line, spring.application.name=first-app. The name appears in every log line, as we will see.
Adding a REST controller
The generated application starts, but it has nothing to say. We add one class next to the main class: a REST controller with two endpoints, one returning text and one returning JSON -HelloController.java - two REST endpoints
package com.javabrahman.firstapp;
import java.time.LocalDate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(@RequestParam(defaultValue = "World") String name) {
return "Hello, " + name + "!";
}
@GetMapping("/info")
public AppInfo info() {
return new AppInfo("first-app", "Spring Boot", LocalDate.of(2026, 11, 6));
}
public record AppInfo(String application, String builtWith, LocalDate date) {
}
}
Explanation of the code
@RestControllermakes the class a bean (component scanning finds it, since it is in the main class's package) and tells Spring MVC that its methods return response bodies rather than view names.@GetMapping("/hello")maps HTTP GET requests for/helloto thehello()method.@RequestParam(defaultValue = "World")binds the query parametername, as in/hello?name=Nancy, falling back toWorldwhen it is absent.info()returns a recordClick to read: record. Spring Boot converts the returned object to JSON automatically, using the Jackson library that the web starter includes.
Running the application
From the project folder, start the application with the Spring Boot Maven plugin -./mvnw spring-boot:run
curl. These are the real responses from the running application -
OUTPUT of the HTTP requests> curl http://localhost:8080/hello
Hello, World!
> curl http://localhost:8080/hello?name=Nancy
Hello, Nancy!
> curl http://localhost:8080/info
{"application":"first-app","builtWith":"Spring Boot","date":"2026-11-06"}
> curl http://localhost:8080/nothing-here
HTTP 404 {"timestamp":"2026-11-06T08:05:59.138Z","status":404,"error":"Not Found","path":"/nothing-here"}
hello(), with and without the name parameter. /info returned the record as JSON, with the LocalDate written as an ISO date. /nothing-here has no mapping, so Spring Boot answered with status 404 and a JSON error body - its built-in error handling, which needs no code.
Reading the startup log
Meanwhile, the application wrote this log to its console - OUTPUT - the application's console log2026-11-06T13:35:56.533+05:30 INFO 28648 --- [first-app] [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) 2026-11-06T13:35:56.611+05:30 INFO 28648 --- [first-app] [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2026-11-06T13:35:56.612+05:30 INFO 28648 --- [first-app] [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/11.0.27] 2026-11-06T13:35:56.816+05:30 INFO 28648 --- [first-app] [ main] b.w.c.s.WebApplicationContextInitializer : Root WebApplicationContext: initialization completed in 2948 ms 2026-11-06T13:35:58.180+05:30 INFO 28648 --- [first-app] [ main] o.s.boot.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' 2026-11-06T13:35:58.681+05:30 INFO 28648 --- [first-app] [nio-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' 2026-11-06T13:35:58.682+05:30 INFO 28648 --- [first-app] [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2026-11-06T13:35:58.687+05:30 INFO 28648 --- [first-app] [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed initialization in 4 ms
Explanation of the log
- Each line shows the date and time, the level (
INFO), the process id, the application name fromspring.application.name, the thread, a shortened logger name, and the message. The format is explained in the tutorial on logging in Spring BootClick to read tutorial: Logging in Spring Boot: SLF4J, Logback and Log Levels. Tomcat initialized with port 8080: auto-configuration found Tomcat on the classpath and created an embedded server on the default port, 8080.Starting Servlet engine: [Apache Tomcat/11.0.27]shows the Tomcat version that Spring Boot 4.1.2 manages.Root WebApplicationContext: initialization completed: the application context, with all beans including our controller, is ready.Tomcat started on port 8080 (http) with context path '/': the server is accepting requests.- The
DispatcherServletlines appeared only when the first request arrived, on a Tomcat request thread (nio-8080-exec-...): Spring MVC's front controller, which routes every request to a controller method, is initialized lazily. - A normal startup also prints the Spring Boot banner, a
Starting FirstAppApplication using Java ... with PID ...line, the active profiles, and a finalStarted FirstAppApplication in ... secondsline. They are switched off in this series' examples (withspring.main.banner-mode=offandspring.main.log-startup-info=false) because the startup line contains file paths of the machine the examples run on.
Running the generated test
Initializr's test class has a single, empty test method -FirstAppApplicationTests.java generated by Spring Initializr
package com.javabrahman.firstapp;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class FirstAppApplicationTests {
@Test
void contextLoads() {
}
}
@SpringBootTest starts the whole application context before the test runs. If any bean cannot be created - a missing dependency, a bad configuration value - the test fails. Running the tests with Maven (only the summary lines of Maven's output are shown) -
OUTPUT of mvn test (summary lines)[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 12.40 s -- in com.javabrahman.firstapp.FirstAppApplicationTests [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] BUILD SUCCESS
Where to go from here
- Change the port: add
server.port=9090toapplication.properties- configuration is covered in application.properties vs application.ymlClick to read tutorial: application.properties vs application.yml in Spring Boot. - Add dependencies later: open start.spring.io again, choose the same options plus the new dependency, and use Explore to see the resulting
pom.xml; then copy the new<dependency>into your project. - Restart automatically on code changes: add DevTools, covered in Spring Boot DevToolsClick to read tutorial: Spring Boot DevTools: Automatic Restart and Productivity.
- Ship it:
./mvnw packagebuilds a jar you can run anywhere withjava -jar.
Summary
In this tutorial we first saw what Spring Initializr is and went through its options - build tool, language, Spring Boot version, metadata, packaging, Java version and dependencies - and generated a project from the website or withcurl. We then walked through the generated project: its folders and Maven wrapper, its pom.xml with the Spring Boot parent and the web starter, and its main class. We added a REST controller, ran the application with spring-boot:run, called it with real HTTP requests, and read the startup log. Lastly, we ran the generated context-loading test and listed the next steps. The next tutorial explains what happened behind the scenes when the web server appeared without any configuration: how Spring Boot auto-configuration worksClick to read tutorial: How Spring Boot Auto-Configuration Works.Spring Boot Tutorials
How Spring Boot Auto-Configuration WorksClick to read tutorial: How Spring Boot Auto-Configuration Works Spring Boot Starters Explained with ExamplesClick to read tutorial: Spring Boot Starters Explained with Examples application.properties vs application.yml in Spring BootClick to read tutorial: application.properties vs application.yml in Spring Boot Type-Safe Configuration with @ConfigurationPropertiesClick to read tutorial: Type-Safe Configuration with @ConfigurationProperties Spring Boot Profiles and Environment-Specific ConfigurationClick to read tutorial: Spring Boot Profiles and Environment-Specific Configuration Logging in Spring Boot: SLF4J, Logback and Log LevelsClick to read tutorial: Logging in Spring Boot: SLF4J, Logback and Log Levels Spring Boot DevTools: Automatic Restart and ProductivityClick to read tutorial: Spring Boot DevTools: Automatic Restart and Productivity
How Spring Boot Auto-Configuration WorksClick to read tutorial: How Spring Boot Auto-Configuration Works Spring Boot Starters Explained with ExamplesClick to read tutorial: Spring Boot Starters Explained with Examples application.properties vs application.yml in Spring BootClick to read tutorial: application.properties vs application.yml in Spring Boot Type-Safe Configuration with @ConfigurationPropertiesClick to read tutorial: Type-Safe Configuration with @ConfigurationProperties Spring Boot Profiles and Environment-Specific ConfigurationClick to read tutorial: Spring Boot Profiles and Environment-Specific Configuration Logging in Spring Boot: SLF4J, Logback and Log LevelsClick to read tutorial: Logging in Spring Boot: SLF4J, Logback and Log Levels Spring Boot DevTools: Automatic Restart and ProductivityClick to read tutorial: Spring Boot DevTools: Automatic Restart and Productivity