← Back to Java series
🌱
Spring Boot
Spring Boot · Prerequisite: previous lecture

23. Getting Started with Spring Boot

Spring Boot lives by **convention over configuration** — you get an **immediately-runnable web app** without dozens of XML lines. It bundles an embedded Tomcat, so `java -jar` launches a server in one line.

Spring BootJavaRESTgetting started
Duration
~1.5-2 hours
Level
📊 Intermediate-Advanced
Prerequisite
🎯 Previous lecture or equivalent knowledge
OUTCOME
Spring Boot lives by **convention over configuration** — you get an **immediately-runnable web app** without dozens of XML lines. It bundles an embedded Tomcat, so `java -jar` launches a server in one line.

What you'll learn

  • 1Know the project layout produced by Spring Initializr
  • 2Understand the role of `@SpringBootApplication`
  • 3Understand dependency injection (DI)
  • 4Change basic settings (port, logs) in `application.properties`
  • 5Run with `mvn spring-boot:run`

Overview

Spring Boot lives by **convention over configuration** — you get an **immediately-runnable web app** without dozens of XML lines. It bundles an embedded Tomcat, so `java -jar` launches a server in one line.

Core Concepts

1) Spring Initializr

Visit https://start.spring.io, pick **Maven**, **Java 21**, and the **Spring Web** starter, then download and unzip the project.

2) Project layout

text
demo/
├── pom.xml
└── src/main/java/com/example/demo/DemoApplication.java

3) `@SpringBootApplication`

java
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
  • `@SpringBootApplication` bundles `@Configuration` + `@EnableAutoConfiguration` + `@ComponentScan`
  • `SpringApplication.run` boots the embedded Tomcat

4) First REST endpoint

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

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() { return "Hello, Spring!"; }
}

Run, then `curl http://localhost:8080/hello` → `Hello, Spring!`

5) Dependency injection (DI)

java
@RestController
public class HelloController {
    private final Greeter greeter;
    public HelloController(Greeter greeter) { this.greeter = greeter; }   // constructor injection

    @GetMapping("/hello")
    public String hello() { return greeter.greet("World"); }
}

Spring creates one bean per `@Component`/`@Service`/etc. and injects them via constructor parameters.

6) `application.properties`

properties
# src/main/resources/application.properties
server.port=8081
logging.level.org.springframework=WARN

Examples

Example 1 — `DemoApplication.java`

java
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);
    }
}

Example 2 — `HelloController.java`

java
package com.example.demo;

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!"; }
}
bash
mvn spring-boot:run
# → http://localhost:8080/hello
curl http://localhost:8080/hello

Example 3 — Constructor-injected service

java
import org.springframework.stereotype.Service;

@Service
public class Greeter {
    public String greet(String name) { return "Hi, " + name + "!"; }
}

@RestController
class GreetController {
    private final Greeter greeter;
    GreetController(Greeter greeter) { this.greeter = greeter; }

    @GetMapping("/greet/{name}")
    public String greet(@PathVariable String name) { return greeter.greet(name); }
}

Example 4 — `application.properties`

properties
server.port=8081
spring.application.name=demo
logging.level.root=INFO

Common Mistakes

  1. Putting your code in the **wrong package** — Spring scans only the package tree of `@SpringBootApplication`
  2. Forgetting `@RestController` and returning a String — Spring tries to resolve it as a view name
  3. Confusing `@Controller` (returns view names) with `@RestController` (returns the body directly)
  4. Hard-coding `localhost:8080` in clients instead of using a config
  5. Using field injection (`@Autowired` on a field) — constructor injection is preferred

Summary

  • Spring Boot = convention over configuration → an executable web app in seconds
  • `@SpringBootApplication` bootstraps everything
  • Use constructor injection — it documents required dependencies

Practice

# Practice - 23. Getting Started with Spring Boot

## Exercise 1 — Generate a project

  • Use Spring Initializr to create `demo` with Spring Web.
  • Add `/ping` returning `pong` and run with `mvn spring-boot:run`.

Expected

text
$ curl http://localhost:8080/ping
pong

## Exercise 2 — Inject a service

  • Add `@Service class Clock { String now() { return java.time.Instant.now().toString(); } }`.
  • Inject into a controller and expose `/now`.

## Solutions After trying it yourself, compare with [`answer/`](./answer/).

Solution code (homework/answer/)

answer/PingController.java

java
package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PingController {
    @GetMapping("/ping")
    public String ping() { return "pong"; }
}

answer/NowController.java

java
package com.example.demo;

import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@Service
class Clock {
    String now() { return java.time.Instant.now().toString(); }
}

@RestController
class NowController {
    private final Clock clock;
    NowController(Clock clock) { this.clock = clock; }

    @GetMapping("/now")
    public String now() { return clock.now(); }
}

Try It Yourself

bash
mvn spring-boot:run
curl http://localhost:8080/hello

Next Lecture

[24_REST](../24_REST_컨트롤러/) — build a full REST API with `@RestController`.

Example code / lecture materials

All lecture materials and example code are openly available on GitHub.

View on GitHub ↗