Your First Spring Boot Application
In this article you’ll create a Spring Boot application, add a REST endpoint, and run it — all in under 10 minutes. Then you’ll understand exactly what each piece does.
What you’ll build: A Spring Boot app that responds to GET /hello with "Hello, Spring Boot!".
Prerequisites
- JDK 21 or higher installed (
java -versionto verify) - Maven 3.9+ installed (
mvn -versionto verify) - An IDE — IntelliJ IDEA (recommended), VS Code with Java extension, or Eclipse
Step 1: Generate the Project
Go to start.spring.io and configure:
| Field | Value |
|---|---|
| Project | Maven |
| Language | Java |
| Spring Boot | 4.0.x |
| Group | com.devopsmonk |
| Artifact | order-service |
| Java | 21 |
Add one dependency: Spring Web
Click Generate. This downloads order-service.zip. Unzip it and open the folder in your IDE.
What Spring Initializr did
It created a complete Maven project with:
- A correct
pom.xmlwith Spring Boot parent and dependencies - A main application class
- An
application.propertiesfile - A test class
You could set this up manually, but Initializr saves 15 minutes and avoids version mismatch mistakes.
Step 2: Understand the Project Structure
order-service/
├── pom.xml # Maven build file
└── src/
├── main/
│ ├── java/
│ │ └── com/devopsmonk/orderservice/
│ │ └── OrderServiceApplication.java # Main class
│ └── resources/
│ ├── application.properties # Configuration
│ ├── static/ # Static web files (empty)
│ └── templates/ # Thymeleaf templates (empty)
└── test/
└── java/
└── com/devopsmonk/orderservice/
└── OrderServiceApplicationTests.java
This is the standard Maven directory layout. Spring Boot expects your code under src/main/java and configuration under src/main/resources.
Step 3: Understand the Main Class
Open OrderServiceApplication.java:
package com.devopsmonk.orderservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
Two things to understand here:
@SpringBootApplication
This single annotation is shorthand for three annotations:
@SpringBootApplication
// is equivalent to:
@SpringBootConfiguration // marks this as a configuration class
@EnableAutoConfiguration // enables auto-configuration
@ComponentScan // scans this package and sub-packages for Spring beans
@EnableAutoConfiguration is the key one — it tells Spring Boot to configure everything automatically based on what’s on the classpath. Since spring-boot-starter-web is present, Spring Boot will auto-configure a web server, Spring MVC, and JSON support.
SpringApplication.run(...)
This bootstraps the application:
- Creates the Spring ApplicationContext (the container that manages all beans)
- Runs auto-configuration
- Starts the embedded Tomcat server on port 8080
- Your application is running
Step 4: Understand the pom.xml
Open pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<!-- Spring Boot parent manages all dependency versions -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.0.0</version>
</parent>
<groupId>com.devopsmonk</groupId>
<artifactId>order-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<!-- Web: Spring MVC + embedded Tomcat + Jackson + validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Testing: JUnit 5 + Mockito + Spring Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Builds an executable JAR with embedded server -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Notice: no version numbers on the dependencies. The spring-boot-starter-parent manages all versions. It contains a tested bill of materials (BOM) — compatible versions of Spring, Tomcat, Jackson, Hibernate, and 200+ more libraries. You don’t need to worry about version conflicts.
Step 5: Add Your First REST Endpoint
Create a new file: src/main/java/com/devopsmonk/orderservice/HelloController.java
package com.devopsmonk.orderservice;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello, Spring Boot!";
}
}
What each annotation does
@RestController — tells Spring this class handles HTTP requests. It combines:
@Controller— registers this class as an MVC controller@ResponseBody— writes the return value directly to the HTTP response body (as JSON/text), instead of looking for a view template
@GetMapping("/hello") — maps HTTP GET /hello requests to this method.
Step 6: Run the Application
Run the main class from your IDE, or from the terminal:
./mvnw spring-boot:run
You’ll see startup output ending with something like:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v4.0.0)
2026-05-03 ... Starting OrderServiceApplication using Java 21
2026-05-03 ... Tomcat started on port 8080 (http) with context path '/'
2026-05-03 ... Started OrderServiceApplication in 1.234 seconds
Now test it:
curl http://localhost:8080/hello
# Hello, Spring Boot!
Or open http://localhost:8080/hello in a browser. You should see Hello, Spring Boot!.
Step 7: Return JSON Instead of a String
Strings are fine for demos, but real APIs return JSON. Create a record to represent a response:
package com.devopsmonk.orderservice;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
record HelloResponse(String message, String version) {}
@GetMapping("/hello")
public HelloResponse hello() {
return new HelloResponse("Hello, Spring Boot!", "4.0");
}
}
Restart and test:
curl http://localhost:8080/hello
# {"message":"Hello, Spring Boot!","version":"4.0"}
Spring Boot automatically serialized the Java record to JSON. This happens because:
spring-boot-starter-webincludes Jackson (JSON library)- Spring Boot auto-configures Jackson when it sees it on the classpath
@RestControllertells Spring to serialize the return value using Jackson
This is auto-configuration in action — zero JSON setup required.
Step 8: Build a Runnable JAR
To deploy your app anywhere:
./mvnw package
java -jar target/order-service-0.0.1-SNAPSHOT.jar
The JAR contains everything: your code, all dependencies, and embedded Tomcat. Copy it to any server with Java 21 and run it. No server installation needed.
# The JAR is ~20MB, includes:
jar tf target/order-service-0.0.1-SNAPSHOT.jar | grep -c ""
# ~1200 entries: your class files + all dependencies
What Just Happened (The Full Picture)
When you ran the application, Spring Boot:
- Started the
mainmethod inOrderServiceApplication SpringApplication.run()bootstrapped the Spring context@EnableAutoConfigurationdetectedspring-boot-starter-webon the classpath- Auto-configuration registered: embedded Tomcat on port 8080, Spring MVC
DispatcherServlet, JacksonObjectMapper, and more @ComponentScanfoundHelloControllerand registered it as a bean- Tomcat started and the
DispatcherServletbegan routing requests GET /hello→HelloController.hello()→ JSON response
HTTP GET /hello
│
▼
Embedded Tomcat (port 8080)
│
▼
Spring MVC DispatcherServlet
│
▼
HelloController.hello()
│
▼
Jackson serializes HelloResponse → JSON
│
▼
HTTP 200 {"message":"Hello, Spring Boot!","version":"4.0"}
Common First-Timer Questions
Q: Where does port 8080 come from?
It’s Spring Boot’s default. Change it in application.properties:
server.port=9090
Q: Do I need to restart every time I change code? Not if you add Spring Boot DevTools:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
DevTools restarts the app automatically when you save a file.
Q: What’s the difference between ./mvnw and mvn?
./mvnw is the Maven Wrapper — it downloads the correct Maven version automatically. mvn uses whatever Maven is installed globally. Use ./mvnw to ensure consistent builds.
Q: Why does @GetMapping exist when there’s also @RequestMapping?
@GetMapping("/hello") is shorthand for @RequestMapping(value = "/hello", method = RequestMethod.GET). The specialized annotations (@GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping) are cleaner and the standard way to write controllers.
Summary
You built a Spring Boot application that:
- Starts in ~1 second
- Exposes a REST endpoint that returns JSON
- Packages as a runnable JAR with embedded server
- Required zero XML configuration
Three files: pom.xml + main class + one controller. That’s the essence of Spring Boot.
Next: Spring Boot Project Structure Explained →
Previous: ← Introduction to Spring Boot