Spring Boot Course · Lesson 1

Your First Running Endpoint

Set up a professional Java toolchain, then go from an empty folder to a live HTTP endpoint you built — all from the command line. This is the foundation every other lesson stands on.

The win

By the end you'll have a running Spring Boot app that answers GET /hello in your browser — the seed of your Library API.

Why Spring Boot exists

You already know Java. So why a framework? Because a real backend needs a web server, JSON handling, configuration, database connections, and a hundred wires connecting them. Plain Spring can do all of this, but historically it meant pages of XML and manual setup.

Spring Boot is the answer to "make Spring just work." It is opinionated: it ships sensible defaults, bundles an embedded server right inside your app, and uses auto-configuration to wire things up based on what's on your classpath. [docs] You write business logic; it handles the plumbing.

The one mental model to keep

Spring is a container. You don't new up your objects and wire them together by hand. You declare the pieces you need; Spring creates them, wires them together, and manages them. Each managed object is a bean; the container holding them is the application context. This is dependency injection, and it's why Spring code is so testable. We'll feel this directly in Lesson 3.

Step 0 — Prerequisites

Everything in this lesson runs from a terminal. The tooling below expects a few standard command-line utilities to already be on your machine: curl (to download installers), zip and unzip (SDKMAN unpacks its downloads with them), and git (to version your project). Check them once:

Terminal window
curl --version
zip --version
unzip -v
git --version

If any command prints command not found, install the missing pieces for your OS:

macOS

Terminal window
# curl, zip and unzip ship with macOS. git comes with the Xcode Command Line Tools:
xcode-select --install

Ubuntu / Debian

Terminal window
sudo apt-get update
sudo apt-get install -y curl zip unzip git

On a minimal Ubuntu install (a fresh server or a Docker image) none of these are present by default, so don't skip this step there. Other Linux distributions have the same packages under the same names in their package manager.

Step 1 — Install Java with SDKMAN

Before any Spring code, you need a JDK. The cleanest way to manage Java on macOS or Linux is SDKMAN! — it installs JDKs (and other JVM tools) and lets you switch versions per project without ever editing PATH or JAVA_HOME by hand. [docs]

Install SDKMAN (one time)
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh" # or just open a new terminal

Now install a JDK. We'll use Temurin 21, the current long-term-support release:

Terminal window
sdk install java 21-tem # download + install Temurin 21 (LTS)
sdk default java 21-tem # make it your default
java -version # verify — should report 21

Run sdk list java to browse every distribution and version. The -tem suffix is Eclipse Temurin; 21 is the version. Anything 17+ works for this course.

Why a version manager?

Real jobs juggle projects pinned to different Java versions. SDKMAN lets you type sdk use java 17-tem in one project and 21-tem in another, instantly. It's the tool most Java teams reach for — worth building the muscle memory now.

Step 2 — Generate the project from the command line

Never hand-write a Spring Boot project — generate it. The web UI at start.spring.io (Spring Initializr) is great for browsing options, but its command-line twin is faster once you know what you want. Install the Spring Boot CLI through SDKMAN:

Terminal window
sdk install springboot
spring --version # verify the CLI is on your PATH

Now generate the Library project in one command:

Terminal window
spring init \
--dependencies=web \
--build=maven \
--java-version=21 \
--group-id=com.example \
--artifact-id=library \
--name=library \
--package-name=com.example.library \
--extract library

This drops a ready-to-run project into a new library/ folder. Each flag maps to a field you'd otherwise click in the web UI: --dependencies=web adds the Spring Web starter, --build=maven picks Maven, and --extract unzips into the folder instead of leaving a .zip. Open library/ in IntelliJ IDEA (or VS Code / Eclipse).

Under the hood, spring init just calls start.spring.io for you — same generator, no browser. Run spring init --list to see every available dependency and option. Prefer clicking? The web Initializr produces an identical project.

Tip — pin the JDK per project

Drop a .sdkmanrc file in the new library/ folder so the project records exactly which JDK it expects:

library/.sdkmanrc
java=21-tem

Run sdk env install to install that JDK, then sdk env to activate it for this directory. Set sdkman_auto_env=true in ~/.sdkman/etc/config and SDKMAN switches to it automatically every time you cd in — so the whole project always builds against the same Java.

What's a starter?

A starter is a curated bundle of dependencies for one job, named spring-boot-starter-*. Passing --dependencies=web pulls in spring-boot-starter-webmvc: a web server, the Spring MVC framework, and a JSON library — all at versions guaranteed to work together. No more dependency-version roulette. (Open pom.xml and you'll see it listed. Before Spring Boot 4 this starter was called spring-boot-starter-web, and you'll still meet that name in older projects.)

Step 3 — Read the two files that matter

Initializr gives you a runnable app already. Two pieces make it tick.

src/main/java/com/example/library/LibraryApplication.java
package com.example.library;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class LibraryApplication {
public static void main(String[] args) {
SpringApplication.run(LibraryApplication.class, args);
}
}

That's a normal Java main method. The magic is one annotation: @SpringBootApplication. It turns on auto-configuration and tells Spring to scan this package for your components. SpringApplication.run(...) boots the container and starts the embedded web server. [guide]

Step 4 — Write your endpoint

Create a new file next to LibraryApplication.java:

src/main/java/com/example/library/HelloController.java
package com.example.library;
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 from the Library API!";
}
}

Two annotations are doing all the work:

Notice you never registered this class anywhere. Component scanning (from @SpringBootApplication) finds @RestController and turns it into a managed bean automatically.

Step 5 — Run it

Run main from your IDE, or from the project root:

Terminal window
# macOS / Linux
./mvnw spring-boot:run
What is ./mvnw?

It's the Maven Wrapper — a small script Spring Initializr placed in your project (mvnw for macOS/Linux, mvnw.cmd for Windows). It downloads and runs the exact version of Maven (the build tool) your project expects, so you never have to install Maven yourself and every machine builds identically. The spring-boot:run part is a Maven goal — provided by the Spring Boot plugin — that compiles your code and launches the app.

Watch the console: you'll see the Spring banner, then a line like Tomcat started on port 8080 and Started LibraryApplication. That "Tomcat" is the embedded server — running inside your Java process. Now open:

http://localhost:8080/hello

You should see your message. That's a real web service, and you built it.

If it doesn't work
  • sdk or spring: command not found? Open a fresh terminal, or re-run source "$HOME/.sdkman/bin/sdkman-init.sh" so your shell picks up SDKMAN.
  • Port 8080 already in use? Something else is running there — stop it, or add server.port=8081 to src/main/resources/application.properties and use that port.
  • 404 Not Found? Make sure HelloController.java is in the same package (com.example.library) or a sub-package of your main class — scanning only looks downward from there.
  • Still stuck? Search the exact error message — the [spring-boot] tag on Stack Overflow has almost certainly seen it.

Check yourself

Retrieval beats re-reading. Answer from memory before clicking.

What does @SpringBootApplication primarily switch on?
Why didn't you have to install or deploy to a separate web server?
You add "Spring Web" in Initializr. In Spring's vocabulary, that single entry is a…
What does the spring init command actually do?

Read this next

Primary source: the official guide Building a RESTful Web Service (≈15 min). It covers exactly what you just did, from the Spring team itself — read it to reinforce, and notice how it returns an object (which becomes JSON) instead of a plain string. That's where Lesson 2 picks up.

Glossary: the terms this lesson introduces are in the Glossary, under Lesson 1 — your quick-reference for every term we use.

Architecture decisions: the 5 choices this lesson makes, each with its reason, are in Architecture Decisions, under Lesson 1.

Code: the project at the end of this lesson, exercises included.

💬 Discuss