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 -version to verify)
  • Maven 3.9+ installed (mvn -version to 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:

FieldValue
ProjectMaven
LanguageJava
Spring Boot4.0.x
Groupcom.devopsmonk
Artifactorder-service
Java21

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.xml with Spring Boot parent and dependencies
  • A main application class
  • An application.properties file
  • 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:

  1. Creates the Spring ApplicationContext (the container that manages all beans)
  2. Runs auto-configuration
  3. Starts the embedded Tomcat server on port 8080
  4. 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:

  1. spring-boot-starter-web includes Jackson (JSON library)
  2. Spring Boot auto-configures Jackson when it sees it on the classpath
  3. @RestController tells 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:

  1. Started the main method in OrderServiceApplication
  2. SpringApplication.run() bootstrapped the Spring context
  3. @EnableAutoConfiguration detected spring-boot-starter-web on the classpath
  4. Auto-configuration registered: embedded Tomcat on port 8080, Spring MVC DispatcherServlet, Jackson ObjectMapper, and more
  5. @ComponentScan found HelloController and registered it as a bean
  6. Tomcat started and the DispatcherServlet began routing requests
  7. GET /helloHelloController.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