← Java 강의 목록으로
🌱
Spring Boot
Spring Boot · 선수: 이전 단원

23. Spring Boot 시작

Spring Boot 는 "설정보다 관습(convention over configuration)" 철학으로 **수십 줄짜리 XML 없이도 즉시 실행 가능한 웹 애플리케이션** 을 만들어 주는 프레임워크입니다. 내장 Tomcat 까지 포함해 `java -jar` 한 줄로 서버가 뜹니다.

Spring BootJavaRESTSpring Boot 시작
소요 시간
약 1.5~2시간
난이도
📊 중급-고급
선수 조건
🎯 이전 단원 또는 동등 지식
결과물
Spring Boot 는 "설정보다 관습(convention over configuration)" 철학으로 **수십 줄짜리 XML 없이도 즉시 실행 가능한 웹 애플리케이션** 을 만들어 주는 프레임워크입니다. 내장 Tomcat 까지 포함해 `java -jar` 한 줄로 서버가 뜹니다.

이 강의에서 배우는 것

  • 1Spring Initializr 가 제공하는 프로젝트 구조를 안다
  • 2`@SpringBootApplication` 의 역할을 안다
  • 3의존성 주입(DI) 의 개념을 이해한다
  • 4`application.properties` 로 포트·로그 등 기본 설정을 바꾼다
  • 5`mvn spring-boot:run` 으로 실행한다

소개

Spring Boot 는 "설정보다 관습(convention over configuration)" 철학으로 **수십 줄짜리 XML 없이도 즉시 실행 가능한 웹 애플리케이션** 을 만들어 주는 프레임워크입니다. 내장 Tomcat 까지 포함해 `java -jar` 한 줄로 서버가 뜹니다.

핵심 개념

1) Spring Initializr

브라우저에서 [start.spring.io](https://start.spring.io) 에 접속해 의존성을 고르면 프로젝트 zip 을 생성해 줍니다. 다음 옵션을 추천:

  • Project: **Maven**
  • Language: **Java**
  • Spring Boot: **3.3.x**
  • Java: **21**
  • Dependencies: **Spring Web** (+ 26편의 H2/JPA)

2) 표준 프로젝트 구조

text
spring-boot-app/
├── pom.xml
├── src/
│   ├── main/
│   │   ├── java/com/codingnow/lecture/spring23/Application.java
│   │   └── resources/application.properties
│   └── test/
│       └── java/com/codingnow/lecture/spring23/ApplicationTests.java

3) `@SpringBootApplication`

java
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

이 한 어노테이션은 **3 개**(`@Configuration`, `@EnableAutoConfiguration`, `@ComponentScan`)를 합친 메타 어노테이션입니다. 같은 패키지·하위 패키지의 Bean 을 자동으로 찾아 등록합니다.

4) 의존성 주입(DI) 의 그림

java
@Service
class HelloService {
    String greet() { return "Hello, Spring!"; }
}

@RestController
class HelloController {
    private final HelloService service;
    HelloController(HelloService service) { this.service = service; }
    @GetMapping("/hello") String hello() { return service.greet(); }
}

Spring 이 `HelloService` 객체를 만들어 컨트롤러 생성자에 자동으로 넘겨줍니다. 호출자가 직접 `new` 하지 않는 패턴이 DI 의 핵심입니다.

5) `application.properties`

properties
server.port=8081
spring.application.name=lecture-spring23
logging.level.root=INFO

핵심 예제

예제 1 — `pom.xml` : Spring Boot 의존성

`pom.xml` (요약):

xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.6</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

`spring-boot-starter-web` 한 의존성에 내장 Tomcat·Jackson(JSON)·Spring MVC 가 모두 포함됩니다.

예제 2 — `Application.java` : 진입점

java
package com.codingnow.lecture.spring23;

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

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

예제 3 — `HelloService.java` + `HelloController.java` : DI 의 첫 사례

`HelloService.java` :

java
package com.codingnow.lecture.spring23;

import org.springframework.stereotype.Service;

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

`HelloController.java` :

java
package com.codingnow.lecture.spring23;

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

@RestController
public class HelloController {
    private final HelloService service;

    public HelloController(HelloService service) {
        this.service = service;
    }

    @GetMapping("/hello")
    public String hello(@RequestParam(defaultValue = "Spring") String name) {
        return service.greet(name);
    }
}

예제 4 — `application.properties`

properties
server.port=8081
spring.application.name=lecture-spring23

실행

bash
cd 06_Spring_Boot/23_Spring_Boot_시작
mvn spring-boot:run

다른 터미널에서:

bash
curl http://localhost:8081/hello
# Hello, Spring!

curl "http://localhost:8081/hello?name=지수"
# Hello, 지수!

전체 예제 코드 (src/)

src/main/java/com/codingnow/lecture/spring23/Application.java

java
package com.codingnow.lecture.spring23;

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

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

src/main/java/com/codingnow/lecture/spring23/HelloController.java

java
package com.codingnow.lecture.spring23;

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

@RestController
public class HelloController {
    private final HelloService service;

    public HelloController(HelloService service) {
        this.service = service;
    }

    @GetMapping("/hello")
    public String hello(@RequestParam(defaultValue = "Spring") String name) {
        return service.greet(name);
    }
}

src/main/java/com/codingnow/lecture/spring23/HelloService.java

java
package com.codingnow.lecture.spring23;

import org.springframework.stereotype.Service;

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

src/main/resources/application.properties

properties
server.port=8081
spring.application.name=lecture-spring23
logging.level.root=INFO

자주 하는 실수

  1. `Application.java` 가 다른 패키지에 있는 컴포넌트를 못 찾음 → 가장 위 패키지에 두기
  2. 포트 충돌 (8080 점유 중) → `server.port` 변경
  3. `mvn spring-boot:run` 으로 실행 안 끝남 (Ctrl+C 로 종료)
  4. 생성자 주입 안 쓰고 `@Autowired` 필드 사용 (테스트 어려움)
  5. Spring Boot 의존성 버전을 일일이 명시 (`parent` 가 관리)

정리

  • `@SpringBootApplication` + `main` 한 쌍이 진입점
  • DI 는 객체를 "직접 만들지 않는" 패턴
  • `application.properties` 로 환경 설정
  • `mvn spring-boot:run` 으로 즉시 실행 가능

과제

# 과제 - 23. Spring Boot 시작

## 문제 — Ping 엔드포인트 + 설정값 노출

  • 위치: `answer/`
  • 핵심 개념: `@RestController`, `@Value`, `application.properties`

요구사항

  • `application.properties` 에 `app.greeting=안녕하세요` 라는 키 추가
  • `PingController` 의 `GET /ping` 이 다음 JSON 을 반환:
json
  {"message": "안녕하세요", "status": "ok"}
  ```
- `@Value("${app.greeting}")` 로 설정값 주입

### 예상 동작

$ mvn spring-boot:run & $ curl http://localhost:8082/ping {"message":"안녕하세요","status":"ok"}

text

## 정답 확인
[`answer/`](./answer/) 폴더의 Maven 프로젝트를 확인하세요.

정답 코드 (homework/answer/)

answer/pom.xml

xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.6</version>
        <relativePath/>
    </parent>

    <groupId>com.codingnow</groupId>
    <artifactId>lecture-spring23-hw</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <properties>
        <java.version>21</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

answer/src/main/java/com/codingnow/lecture/spring23hw/Application.java

java
package com.codingnow.lecture.spring23hw;

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

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

answer/src/main/java/com/codingnow/lecture/spring23hw/PingController.java

java
package com.codingnow.lecture.spring23hw;

import java.util.Map;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PingController {
    private final String greeting;

    public PingController(@Value("${app.greeting}") String greeting) {
        this.greeting = greeting;
    }

    @GetMapping("/ping")
    public Map<String, String> ping() {
        return Map.of("message", greeting, "status", "ok");
    }
}

answer/src/main/resources/application.properties

properties
server.port=8082
spring.application.name=lecture-spring23-hw
app.greeting=안녕하세요

직접 해 보기

bash
cd 06_Spring_Boot/23_Spring_Boot_시작
mvn spring-boot:run
# 다른 터미널
curl http://localhost:8081/hello

다음 단원

[24_REST_컨트롤러](../24_REST_컨트롤러/) — `@RestController` 와 다양한 매핑을 본격적으로 다룹니다.

예제 코드 / 강의 자료

전체 강의 자료와 예제 코드는 GitHub에서 자유롭게 받아볼 수 있습니다.

GitHub에서 보기 ↗