Spring Boot
Creating Spring Boot Project
There are four ways to create a Spring Boot project — Spring Initializr web UI, IDE integration, Spring Boot CLI, and manual setup. Each approach produces the same project structure. Understanding every method and what gets generated lets you bootstrap projects confidently and understand exactly what every generated file does.
Four Ways to Create a Spring Boot Project
Every Spring Boot project starts the same way — a pom.xml or build.gradle with the Spring Boot parent, a main application class annotated with @SpringBootApplication, an application.properties file, and a test class. The four creation methods all produce this same structure — they differ only in how much UI or tooling is involved.
Method 1 — Spring Initializr web UI (start.spring.io): fill a form, select dependencies, download a ZIP. No tooling required — works in any browser.
Method 2 — IDE integration: IntelliJ IDEA, VS Code, and Eclipse all have built-in Initializr integration. You go through a wizard inside the IDE and the project opens immediately.
Method 3 — Spring Boot CLI: the spring init command generates a project from the terminal. Scriptable and automatable.
Method 4 — Manual setup: create the directory structure, write the pom.xml, and create the main class by hand. The only approach that teaches you what every piece does.
Method 1 — Spring Initializr Web UI
start.spring.io is the official project generator. Fill in the form, select dependencies, and download a ZIP that contains a complete, immediately runnable project.
Java
// Steps at start.spring.io:
// 1. Project — choose your build tool:
// Maven → pom.xml + mvnw wrapper
// Gradle (Groovy) → build.gradle + gradlew wrapper
// Gradle (Kotlin) → build.gradle.kts + gradlew wrapper
// 2. Language:
// Java / Kotlin / Groovy
// 3. Spring Boot version:
// Always choose the latest RELEASE (not SNAPSHOT or M/RC)
// 3.2.x requires Java 17 minimum
// 3.3.x requires Java 17 minimum (latest LTS as of 2024)
// 4. Project Metadata:
// Group: com.example
// Artifact: myapp
// Name: myapp
// Description: My Spring Boot Application
// Package name: com.example.myapp (auto-generated)
// Packaging: Jar (self-contained executable)
// Java: 21 (latest LTS — recommended)
// 5. Add Dependencies — search and select:
// Spring Web → spring-boot-starter-web
// Spring Data JPA → spring-boot-starter-data-jpa
// Spring Security → spring-boot-starter-security
// Validation → spring-boot-starter-validation
// Spring Boot Actuator → spring-boot-starter-actuator
// Spring Boot DevTools → spring-boot-devtools
// Lombok → lombok
// MySQL Driver → mysql-connector-j
// H2 Database → h2 (for dev/test)
// Flyway Migration → flyway-core
// 6. Click GENERATE → downloads myapp.zip
// 7. Unzip and open in IDE:
// unzip myapp.zip && cd myapp
// ./mvnw spring-boot:run ← runs immediatelyMethod 2 — IntelliJ IDEA
IntelliJ IDEA has built-in Spring Initializr support in both Community and Ultimate editions. The wizard mirrors start.spring.io but integrates directly with the IDE.
Java
// Steps in IntelliJ IDEA 2023+:
// 1. File → New → Project
// 2. Select "Spring Boot" from the left panel
// (called "Spring Initializr" in older versions)
// 3. Configure the project:
// Name: myapp
// Location: /path/to/workspace/myapp
// Language: Java
// Type: Maven
// Group: com.example
// Artifact: myapp
// Package name: com.example.myapp
// JDK: 21 (select from dropdown — download if not installed)
// Java: 21
// Packaging: Jar
// 4. Click Next → Dependencies screen:
// Search "web" → check Spring Web
// Search "jpa" → check Spring Data JPA
// Search "security" → check Spring Security
// Search "validation" → check Validation
// Search "actuator" → check Spring Boot Actuator
// Search "devtools" → check Spring Boot DevTools
// Search "lombok" → check Lombok
// Search "mysql" → check MySQL Driver
// 5. Click Create
// IntelliJ downloads the project, imports it, and opens it
// Maven sync runs automatically — all dependencies downloaded
// 6. Run the application:
// Click the green play button next to main() in MyappApplication.java
// Or: right-click MyappApplication → Run 'MyappApplication.main()'
// Or: use the Run toolbar at the top of the IDE
// IntelliJ Ultimate extras (not in Community):
// - Spring tool window showing all beans, endpoints, and mappings
// - @RequestMapping endpoint navigation
// - Spring Data JPA query inspection
// - Spring Boot run dashboardMethod 3 — VS Code
VS Code supports Spring Boot project creation through the Spring Boot Extension Pack. The experience is command-palette driven and produces the same project as start.spring.io.
Java
// Prerequisites — install from Extensions marketplace:
// "Spring Boot Extension Pack" by VMware
// (includes Spring Initializr, Spring Boot Tools, Spring Boot Dashboard)
// Create a project:
// 1. Open Command Palette: Ctrl+Shift+P (Win/Linux) or Cmd+Shift+P (Mac)
// 2. Type: Spring Initializr: Create a Maven Project
// Or: Spring Initializr: Create a Gradle Project
// 3. Follow the prompts (one question at a time):
// Spring Boot version: 3.2.4
// Project language: Java
// Group Id: com.example
// Artifact Id: myapp
// Packaging type: Jar
// Java version: 21
// Search dependencies: web → Enter to add
// Search dependencies: data-jpa → Enter to add
// Search dependencies: security → Enter to add
// Search dependencies: (press Enter with empty search to finish)
// 4. Choose destination folder → project is generated and opened
// VS Code Spring Boot features after project creation:
// Spring Boot Dashboard (left sidebar):
// - Start/stop/restart applications
// - View running beans
// - Live application metrics
// application.properties auto-completion:
// - Type spring.datasource. → shows all available properties
// - Hover over any property → shows description and default value
// @RequestMapping navigation:
// - Click the endpoint URL hint above controller methods
// - Opens browser to that endpoint
// Run and debug:
// 1. Open MyappApplication.java
// 2. Click the "Run" CodeLens above main()
// 3. Or: F5 to start with debugger attachedMethod 4 — Spring Boot CLI
The spring init command generates projects from the terminal — identical to start.spring.io but scriptable. Ideal for automation, CI pipelines, or developers who prefer the command line.
Shell
# Install Spring Boot CLI via SDKMAN (recommended):
sdk install springboot
spring --version # Spring CLI v3.2.4
# Basic project — Spring Web only:
spring init --dependencies=web myapp
# Full REST API project:
spring init \
--build=maven \
--java-version=21 \
--boot-version=3.2.4 \
--group-id=com.example \
--artifact-id=myapp \
--name="My Application" \
--package-name=com.example.myapp \
--packaging=jar \
--dependencies=web,data-jpa,security,validation,actuator,devtools,lombok \
myapp
# Change into the project and run:
cd myapp && ./mvnw spring-boot:run
# Gradle project:
spring init \
--build=gradle \
--dependencies=web,data-jpa,security \
myapp-gradle
# Kotlin project:
spring init \
--language=kotlin \
--build=gradle \
--dependencies=web,data-jpa \
myapp-kotlin
# Generate into current directory:
spring init --dependencies=web,data-jpa .
# List all available dependencies:
spring init --list
# List available Spring Boot versions:
spring init --list | grep "Available Spring Boot"
# Via curl (no CLI needed — uses the Initializr REST API):
curl https://start.spring.io/starter.zip \
-d type=maven-project \
-d language=java \
-d bootVersion=3.2.4 \
-d groupId=com.example \
-d artifactId=myapp \
-d javaVersion=21 \
-d dependencies=web,data-jpa,security,actuator \
-o myapp.zip && unzip myapp.zip -d myappMethod 5 — Manual Setup
Creating a Spring Boot project from scratch — without any generator — teaches you exactly what every part does. This is the most educational approach and demystifies the generated structure.
Shell
# Step 1 — Create the directory structure:
mkdir -p myapp/src/main/java/com/example/myapp
mkdir -p myapp/src/main/resources
mkdir -p myapp/src/test/java/com/example/myapp
cd myappThe Generated pom.xml — Every Line Explained
Understanding every element in the generated pom.xml removes the mystery from Spring Boot's build configuration.
XML
<!-- pom.xml — complete annotated example: -->
<?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>
<!-- ① Inherit from Spring Boot — provides dependency management and plugin config: -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version>
<relativePath/> <!-- look in Maven repo, not local filesystem -->
</parent>
<!-- ② Your project coordinates — uniquely identify this project: -->
<groupId>com.example</groupId>
<artifactId>myapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>myapp</name>
<description>My Spring Boot Application</description>
<!-- ③ Java version — inherited by compiler plugin: -->
<properties>
<java.version>21</java.version>
</properties>
<!-- ④ Dependencies — no versions needed (managed by parent BOM): -->
<dependencies>
<!-- Spring MVC + embedded Tomcat + Jackson: -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- JPA + Hibernate + HikariCP + Spring Data: -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Spring Security — authentication + authorization: -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Bean Validation (Jakarta Validation + Hibernate Validator): -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- Production monitoring endpoints: -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- MySQL JDBC driver — scope=runtime: not needed at compile time: -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Lombok — compile-time code generation: -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional> <!-- not included in dependents -->
</dependency>
<!-- DevTools — auto-restart in development:
scope=runtime: only on classpath at runtime, not compile time
optional=true: not transitively included — dev only -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- Test dependencies — only on test classpath: -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<!-- Includes: JUnit 5, Mockito, AssertJ, MockMVC, Spring Test -->
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!-- ⑤ Build configuration: -->
<build>
<plugins>
<!-- Spring Boot Maven plugin:
- Repackages the JAR into an executable fat JAR on mvn package
- Provides spring-boot:run goal
- Excludes Lombok from the final JAR -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>The Main Application Class
Every Spring Boot project has exactly one main class annotated with @SpringBootApplication. Understanding what this annotation does and why the class must be in the root package is foundational.
Java
// src/main/java/com/example/myapp/MyappApplication.java
package com.example.myapp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
// Equivalent to these three annotations combined:
// @Configuration → this class can define @Bean methods
// @EnableAutoConfiguration → trigger Spring Boot's auto-configuration
// @ComponentScan → scan com.example.myapp and ALL sub-packages
public class MyappApplication {
public static void main(String[] args) {
SpringApplication.run(MyappApplication.class, args);
// 1. Creates the Spring ApplicationContext
// 2. Runs auto-configuration
// 3. Instantiates and wires all beans
// 4. Starts the embedded Tomcat server
// 5. Publishes ApplicationReadyEvent
}
}
// CRITICAL: This class must be in the ROOT package:
// com/example/myapp/MyappApplication.java ← CORRECT
// @ComponentScan scans com.example.myapp.* — finds everything
// com/example/myapp/config/MyappApplication.java ← WRONG
// @ComponentScan only scans com.example.myapp.config.*
// Misses controllers, services, repositories in sibling packages
// src/test/java/com/example/myapp/MyappApplicationTests.java
package com.example.myapp;
import org.springframework.boot.test.context.SpringBootTest;
import org.junit.jupiter.api.Test;
@SpringBootTest
class MyappApplicationTests {
@Test
void contextLoads() {
// Verifies the entire Spring ApplicationContext starts without errors
// This is the first test to run after adding any new dependency
// If this fails, you have a configuration problem — fix it before anything else
}
}First Run and Verification
After creating the project, verifying it runs correctly is the first thing to do — before writing any application code.
Shell
# Run using the Maven wrapper (no Maven installation required):
./mvnw spring-boot:run
# Expected output (truncated):
# . ____ _ __ _ _
# /\\ / ___'_ __ _ _(_)_ __ __ _ \\ \\ \\
# ( ( )\\___ | '_ | '_| | '_ \/ _` | \\ \\ \\
# \\/ ___)| |_)| | | | | || (_| | ) ) ) )
# ' |____| .__|_| |_|_| |_\\__, | / / / /
# =========|_|==============|___/=/_/_/_/
# :: Spring Boot :: (v3.2.4)
#
# INFO --- [main] c.e.myapp.MyappApplication : Starting MyappApplication
# INFO --- [main] c.e.myapp.MyappApplication : Started MyappApplication in 2.341 seconds
# Run the context load test:
./mvnw test
# Build the executable JAR:
./mvnw clean package
# Run the JAR directly:
java -jar target/myapp-0.0.1-SNAPSHOT.jar
# Run with a specific profile:
./mvnw spring-boot:run -Dspring-boot.run.profiles=dev
# Run with a property override:
./mvnw spring-boot:run -Dspring-boot.run.arguments="--server.port=9090"
# Check the application is running:
curl http://localhost:8080/actuator/health
# {"status":"UP"} ← if spring-boot-starter-actuator is included
# Common startup failures and fixes:
# "Port 8080 already in use"
# → server.port=9090 in application.properties
# → Or: kill the process using port 8080
# "Failed to configure a DataSource"
# → Add spring.datasource.url to application.properties
# → Or: add H2 dependency for in-memory database
# → Or: exclude DataSourceAutoConfiguration if no database needed
# "Cannot find symbol" / compile errors
# → Ensure Lombok annotation processor is configured
# → IntelliJ: Enable annotation processing in Settings → Build → CompilerFirst REST Endpoint
With the project running, adding the first REST endpoint verifies the full request-handling stack works — routing, serialization, and response.
Java
// src/main/java/com/example/myapp/controller/HelloController.java
package com.example.myapp.controller;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.Map;
@RestController
@RequestMapping("/api")
public class HelloController {
@GetMapping("/hello")
public Map<String, Object> hello(
@RequestParam(defaultValue = "World") String name) {
return Map.of(
"message", "Hello, " + name + "!",
"timestamp", LocalDateTime.now(),
"status", "OK"
);
}
@PostMapping("/echo")
public Map<String, Object> echo(@RequestBody Map<String, Object> body) {
body.put("echoed", true);
body.put("timestamp", LocalDateTime.now());
return body;
}
}
// Test it:
// curl http://localhost:8080/api/hello
// {"message":"Hello, World!","timestamp":"2024-01-15T10:30:00","status":"OK"}
// curl http://localhost:8080/api/hello?name=Alice
// {"message":"Hello, Alice!","timestamp":"2024-01-15T10:30:01","status":"OK"}
// curl -X POST http://localhost:8080/api/echo \
// -H "Content-Type: application/json" \
// -d '{"key":"value","number":42}'
// {"key":"value","number":42,"echoed":true,"timestamp":"2024-01-15T10:30:02"}
// Note: if Spring Security is included, all endpoints require authentication by default
// Add this to application.properties to disable security for initial development:
// spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
// Or configure a SecurityFilterChain bean that permits all requests temporarily