Skip to main content
Java intermediate Lesson 49 of 58

Spring Boot — Introduction

Get started with Spring Boot — what it is, how it differs from Spring Framework, project setup with Spring Initializr, and your first REST endpoint.

Spring Boot is the standard way to build Java backend applications today. It removes the boilerplate configuration of plain Spring Framework and lets you go from zero to a running HTTP server in minutes. The key idea is convention over configuration — Spring Boot makes sensible choices for you based on what’s on the classpath, and you only override the things that need to differ.

Creating a Project

The fastest way is start.spring.io. It generates a complete, buildable project with your chosen dependencies wired up:

  1. Project: Maven | Language: Java | Spring Boot: 3.x (latest)
  2. Group: com.example | Artifact: demo
  3. Java: 21
  4. Dependencies: Spring Web, Spring Data JPA, MySQL Driver, Validation
  5. Click Generate — download and unzip

Or use IntelliJ IDEA: File → New Project → Spring Initializr.

Project Structure

Spring Boot follows a standard layout. Understanding where things live helps you know where to put your own code:

demo/
├── src/
│   ├── main/
│   │   ├── java/com/example/demo/
│   │   │   └── DemoApplication.java        ← entry point (@SpringBootApplication)
│   │   └── resources/
│   │       ├── application.properties       ← all configuration lives here
│   │       └── static/                      ← static files (CSS, JS, images)
│   └── test/
│       └── java/com/example/demo/
│           └── DemoApplicationTests.java    ← Spring context integration tests
├── pom.xml                                  ← dependencies and build config
└── mvnw                                     ← Maven wrapper (no local Maven needed)

Entry Point

The main class is the only required piece of boilerplate. @SpringBootApplication triggers component scanning, auto-configuration, and marks the class as a configuration source — all three in one annotation. SpringApplication.run bootstraps the entire framework and starts the embedded server.

package com.example.demo;

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

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args); // starts Tomcat on port 8080
    }
}

Your First REST Endpoint

@RestController tells Spring that this class handles HTTP requests and that the return values should be written directly to the response body (as JSON, or plain text for strings). @RequestMapping sets the base path for all methods in the class.

package com.example.demo;

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class HelloController {

    // Handles GET /api/hello — no path variable, always returns the same greeting
    @GetMapping("/hello")
    public String hello() {
        return "Hello, Spring Boot!";
    }

    // Handles GET /api/hello/{name} — Spring extracts the name from the URL
    @GetMapping("/hello/{name}")
    public String helloName(@PathVariable String name) {
        return "Hello, " + name + "!";
    }
}

Run with:

./mvnw spring-boot:run
# or build first, then run the JAR
./mvnw package && java -jar target/demo-0.0.1-SNAPSHOT.jar

Test:

curl http://localhost:8080/api/hello
# Hello, Spring Boot!

curl http://localhost:8080/api/hello/Alice
# Hello, Alice!

application.properties

All configuration — database URLs, logging levels, server port — lives in application.properties. Spring Boot reads this file automatically at startup. You can override any value at runtime with an environment variable or command-line argument without touching the file.

# Server
server.port=8080

# Database (if using JPA)
spring.datasource.url=jdbc:mysql://localhost:3306/demodb
spring.datasource.username=root
spring.datasource.password=${DB_PASSWORD}   # reads from DB_PASSWORD env variable
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# JPA
spring.jpa.hibernate.ddl-auto=update        # auto-create/update tables in dev
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect

# Logging
logging.level.com.example=DEBUG
logging.level.org.springframework.web=INFO

Use application.yml for a cleaner format (same effect):

server:
  port: 8080

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demodb
    username: root
    password: ${DB_PASSWORD}
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: false

logging:
  level:
    com.example: DEBUG

Spring Boot Starters

Starters are curated dependency bundles. Adding one starter pulls in everything you need for that feature — the right libraries, at compatible versions, with auto-configuration wired up. This is one of Spring Boot’s biggest quality-of-life improvements over plain Spring.

StarterWhat it includes
spring-boot-starter-webSpring MVC, embedded Tomcat, Jackson JSON
spring-boot-starter-data-jpaJPA, Hibernate, Spring Data
spring-boot-starter-securitySpring Security
spring-boot-starter-validationBean Validation (Hibernate Validator)
spring-boot-starter-testJUnit 5, Mockito, Spring Test
spring-boot-starter-actuatorHealth checks, metrics endpoints
spring-boot-starter-mailJavaMail for sending email

Running and Building

# Run in dev mode (hot restart on code changes when devtools is on the classpath)
./mvnw spring-boot:run

# Build a self-contained executable JAR
./mvnw clean package

# Run the JAR directly — no Maven needed on the target machine
java -jar target/demo-0.0.1-SNAPSHOT.jar

# Activate a specific profile (e.g. prod settings)
java -jar target/demo.jar --spring.profiles.active=prod

# Override any property at runtime without rebuilding
java -jar target/demo.jar --server.port=9090

Spring Boot DevTools

DevTools watches your classpath for changes and restarts the application automatically. This cuts the inner dev loop from “stop, rebuild, restart” to “save file, wait 1 second.” Add it as an optional runtime dependency so it never ends up in production builds.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>  <!-- excluded from final JAR automatically -->
</dependency>

Profiles

Profiles let you maintain different configuration for different environments — a common pattern is dev with a local database and verbose logging, and prod with a managed database and minimal logging. The shared defaults live in application.properties; profile-specific files add or override only what differs.

src/main/resources/
├── application.properties          ← shared defaults (applies in all profiles)
├── application-dev.properties      ← development overrides
└── application-prod.properties     ← production overrides

application-prod.properties:

spring.jpa.hibernate.ddl-auto=validate   # never auto-migrate schema in production
logging.level.com.example=WARN           # less noise in production logs

Activate:

java -jar app.jar --spring.profiles.active=prod
# or set the environment variable
export SPRING_PROFILES_ACTIVE=prod

Actuator — Health and Metrics

Actuator exposes built-in HTTP endpoints for monitoring your application’s health, configuration, and JVM metrics. It’s essential for production deployments — load balancers and orchestrators like Kubernetes use the /health endpoint to decide whether to send traffic to an instance.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
# Expose only the endpoints you need — never expose all in production
management.endpoints.web.exposure.include=health,info,metrics
management.endpoint.health.show-details=when-authorized
curl http://localhost:8080/actuator/health
# {"status":"UP","components":{"db":{"status":"UP"},"diskSpace":{"status":"UP"}}}

curl http://localhost:8080/actuator/metrics/jvm.memory.used

This is the foundation everything else builds on. Next: Dependency Injection — how Spring manages your objects.

Frequently Asked Questions

What is the difference between Spring and Spring Boot?
Spring Framework is a comprehensive DI and web framework that requires significant XML or Java configuration. Spring Boot is an opinionated layer on top of Spring that auto-configures everything based on what's on the classpath — you get a working application with zero configuration. Spring Boot also embeds a web server (Tomcat by default) so you run a plain JAR rather than deploying a WAR.
What does @SpringBootApplication do?
@SpringBootApplication is a convenience annotation that combines three annotations: @Configuration (marks the class as a bean source), @EnableAutoConfiguration (triggers Spring Boot's auto-configuration), and @ComponentScan (scans the package and sub-packages for @Component, @Service, @Repository, @Controller beans).
What is auto-configuration?
Spring Boot looks at the JARs on your classpath and automatically configures beans you'd otherwise set up manually. For example, if spring-boot-starter-data-jpa is present and a DataSource bean is configured, Spring Boot automatically sets up a JPA EntityManagerFactory, TransactionManager, and JpaRepositories — without a single line of configuration from you.