The fastest way to understand Spring Boot is to build one small app that actually runs. In about fifteen minutes you can go from an empty folder to a web application answering HTTP requests — no server to install, no XML to write. This walkthrough takes you through every step and explains what each part does.
Before you start, make sure you have a JDK (17 or newer) and an IDE such as IntelliJ IDEA or VS Code. If Java itself is new to you, the install Java guide gets your environment ready first.
Step 1: Generate the project
Spring Boot projects start at Spring Initializr (start.spring.io). Rather than assemble dependencies by hand, you pick a few options and it produces a ready-to-run project.
Choose these settings:
- Project: Maven
- Language: Java
- Spring Boot: the latest stable release
- Dependencies: Spring Web
The single most important choice is adding Spring Web — that is the starter which brings in Spring MVC and an embedded Tomcat. Starters are what make one dependency pull in a whole feature; the idea is covered in Spring Boot starters. Download the zip, unzip it, and open the folder in your IDE.
Step 2: Read the main class
Every Spring Boot project has one entry-point class that Initializr generated for you. Open it and you will see this:
package com.codebegun.shop;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ShopApplication {
public static void main(String[] args) {
SpringApplication.run(ShopApplication.class, args);
}
}
Two lines do all the work. @SpringBootApplication switches on auto-configuration and tells
Spring to scan this package and everything below it for your components. SpringApplication.run(...)
boots the container, starts the embedded server, and keeps the app alive. Because it is a
normal main method, you run it exactly like any Java program.
Pro tip: Keep this main class in the root package of your project (here
com.codebegun.shop). Component scanning only reaches the main class's package and its subpackages, so a controller placed in a sibling or parent package will silently not be found. This one rule prevents the most common "my endpoint returns 404" confusion.
Step 3: Run it once, empty
Before adding any code, run the main class. Watch the console — you will see the Spring banner and a line like:
Tomcat started on port(s): 8080 (http)
Started ShopApplication in 1.42 seconds
That confirms the embedded server is live. Visiting http://localhost:8080 now shows an error page, because you have not defined any endpoints yet — which is exactly the next step. The fact that a server started at all, with zero configuration from you, is auto-configuration in action; see what is Spring Boot for why that happens.
Step 4: Add your first endpoint
Create a new class in the same package (or a subpackage) for a REST controller.
package com.codebegun.shop;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController {
@GetMapping("/hello")
public String hello(@RequestParam(defaultValue = "World") String name) {
return "Hello, " + name + "! Your Spring Boot app is running.";
}
}
Two annotations carry the meaning. @RestController marks this class as a web component
whose return values become the HTTP response body — it is a bean the container manages, just
like the ones in Spring beans. @GetMapping("/hello")
maps HTTP GET requests for /hello to this method. The @RequestParam reads a query
parameter, defaulting to "World" when absent.
Step 5: Run and test
Restart the application and visit the endpoint in a browser or with curl:
# Default greeting
curl http://localhost:8080/hello
# -> Hello, World! Your Spring Boot app is running.
# Pass a query parameter
curl "http://localhost:8080/hello?name=Ravi"
# -> Hello, Ravi! Your Spring Boot app is running.
That is a complete, running Spring Boot web application. No Tomcat install, no WAR deployment, no XML — you wrote a main class and a controller, and the framework did the rest.
Understand the project layout
Before tweaking anything, it helps to know where things live, because the layout is a convention every Spring Boot project shares. Learn it once and every project you open looks familiar.
src/main/java— your Java code, with the main class at the root package.src/main/resources— configuration and static files, includingapplication.properties.src/test/java— your tests; Boot generates one test class to start you off.pom.xml(Maven) — your dependencies, including the starters you selected.
The single most important habit is package placement. Because @SpringBootApplication
scans downward from its own package, every controller, service and component you write should
sit in that package or a subpackage of it. Teams usually create subpackages like controller,
service and repository under the root, which keeps the code organised while staying inside
the scan path. The beans that scanning discovers are the same container-managed objects
described in Spring beans.
Add a service behind the controller
A controller that does everything itself gets messy fast. The convention is to keep controllers thin and push logic into a service — a separate bean the container injects. This also shows dependency injection working in your own code.
package com.codebegun.shop;
import org.springframework.stereotype.Service;
@Service
public class GreetingService {
public String greet(String name) {
return "Hello, " + name + "! Your Spring Boot app is running.";
}
}
Now the controller simply asks for the service through its constructor, and Spring supplies
it — you never write new GreetingService():
@RestController
public class GreetingController {
private final GreetingService greetingService;
// Single constructor: Spring injects the GreetingService bean automatically
public GreetingController(GreetingService greetingService) {
this.greetingService = greetingService;
}
@GetMapping("/hello")
public String hello(@RequestParam(defaultValue = "World") String name) {
return greetingService.greet(name);
}
}
This tiny refactor is worth internalising early. It is the same constructor injection covered in dependency injection in Spring, and the controller-service split is how nearly every real Spring Boot codebase is organised. The behaviour from the browser is identical; the structure is now ready to grow.
Step 6: Tweak a setting
To prove configuration is in your hands, open src/main/resources/application.properties and
change the port:
server.port=9090
Restart and the app now serves on 9090 instead of 8080. That single properties file is where you control ports, database URLs, logging levels and more, without touching code. The full range of what you can set there is in application.properties.
Common mistake: Editing the code, then wondering why the endpoint still behaves the old way. A running Spring Boot app does not pick up changes until you restart it (or use devtools for automatic restart). If a change is not showing, stop and rerun the app first — it is almost always a stale process, not a code bug.
When it will not start: reading the error
Your first few runs will occasionally fail to start, and Spring Boot's startup log is unusually good at telling you why — if you read it. When something goes wrong, Boot prints a clearly boxed section:
***************************
APPLICATION FAILED TO START
***************************
Description:
Web server failed to start. Port 8080 was already in use.
Action:
Identify and stop the process listening on port 8080, or configure
this application to listen on another port.
That block names the problem (port in use) and the fix (stop the other process or change the
port). The two failures you will meet most often as a beginner are this port clash — usually a
previous run of the app still holding the port — and a NoSuchBeanDefinitionException, which
means the container could not find a bean to inject, almost always because a class sits outside
the scan path or is missing its @Component/@Service annotation. Read the "Description" and
"Action" lines first; they resolve most startup issues in seconds.
What you just learned
You generated a project with the Web starter, understood that @SpringBootApplication enables
auto-configuration and scanning, and saw SpringApplication.run boot an embedded server. You
added a @RestController with a @GetMapping endpoint, ran it, and even changed a setting
through application.properties. That is the full loop of Spring Boot development in
miniature.
From here, the natural next move is turning this toy endpoint into a proper API — handling POST requests, returning JSON objects, and structuring controllers and services — which is exactly what building a REST API with Spring Boot covers. Keep going through the Spring Boot learning hub and you will have a job-ready backend skill faster than you expect.
Frequently Asked Questions
How do I create a Spring Boot project?
What does @SpringBootApplication do?
How do I run a Spring Boot application?
Why is my Spring Boot controller returning 404?
What port does Spring Boot run on by default?
Want to Build Your Career in Java Full Stack with AI?
Join CodeBegun and train with working industry engineers — Explore the Program

