Spring Boot 개요와 시작하기

6주 Java DI를 Spring Bean으로 연결하고 DTO·Service·Controller의 첫 API 실행하기

이번 문서에서 만드는 것

6주는 5주의 생성자 주입을 Spring Bean으로 옮기고 HTTP 목록 API를 실행합니다. Java·컬렉션·DI를 먼저 완료합니다. 결과는 GET /api/members의 JSON이며 DB와 로그인은 아직 추가하지 않습니다.

Spring Boot는 의존성과 설정을 바탕으로 애플리케이션을 구성합니다. @SpringBootApplication 아래에서 컴포넌트를 찾고 @Service 등의 Bean을 생성자에 연결합니다. “자동”이라는 말은 객체의 책임과 의존성이 없어졌다는 뜻이 아닙니다.

프로젝트 생성

Spring Initializr에서 다음을 선택합니다. 이 문서 작성 시 공식 요구사항의 안정 버전은 Spring Boot 4.1.1이며 Java 21로 실습합니다. M·RC·SNAPSHOT 대신 안정 버전을 선택하고 정확한 버전을 기록합니다.

항목실습 값
Project / LanguageGradle - Groovy / Java
Group / Artifactcom.example / lion
Package namecom.example.lion
Java21
DependenciesSpring Web, Validation

ZIP을 풀고 build.gradle이 있는 폴더를 IDE로 엽니다. 이전 콘솔 폴더에 덮어쓰지 않습니다. 다운로드된 Gradle Wrapper를 사용하므로 별도의 전역 Gradle 설치가 필요하지 않습니다.

Shell
# macOS/Linux./gradlew test./gradlew bootRun

Windows PowerShell에서는 각각 .\gradlew.bat test, .\gradlew.bat bootRun입니다. 이후 문서의 Gradle 명령도 같은 방식으로 바꿉니다. 실제 JDK가 맞는지는 Wrapper 출력과 IDE 설정을 함께 확인합니다.

DTO·Service·Controller 연결하기

아래 세 파일은 모두 src/main/java/com/example/lion/에 만듭니다. 생성된 LionApplication.java는 유지합니다.

MemberResponse.java:

Java
package com.example.lion;
public record MemberResponse(long id, String name) {}

record는 응답용 데이터 구조를 간결하게 표현합니다. 구성 요소의 참조는 재할당하지 않지만 List 같은 가변 객체를 필드로 담으면 그 내부까지 자동으로 불변이 되는 것은 아닙니다.

MemberService.java:

Java
package com.example.lion;
import java.util.List;import org.springframework.stereotype.Service;
@Servicepublic class MemberService {    public List<MemberResponse> findAll() {        return List.of(new MemberResponse(1, "가람"));    }}

MemberController.java:

Java
package com.example.lion;
import java.util.List;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;
@RestController@RequestMapping("/api/members")public class MemberController {    private final MemberService service;
    public MemberController(MemberService service) { this.service = service; }
    @GetMapping    public List<MemberResponse> findAll() { return service.findAll(); }}

서버를 재시작하고 http://localhost:8080/api/members를 엽니다. [{"id":1,"name":"가람"}]과 200을 확인합니다. Controller는 HTTP와 응답 DTO를, Service는 목록을 제공하는 유스케이스를 담당합니다. 다음 주에는 실제 입력과 변경이 생기므로 Service 구현도 달라집니다.

설정의 범위 이해하기

src/main/resources/application.propertiesserver.port=8081을 잠시 설정하면 서버 주소도 8081로 바뀝니다. 확인 후 다시 8080으로 복구합니다. 환경변수·프로필·설정 파일 중 어떤 값이 적용되는지 공식 우선순위를 확인하고 비밀번호를 커밋하지 않습니다.

@ConfigurationProperties는 설정을 타입으로 묶는 도구입니다. 애너테이션만 붙였다고 등록과 유효성 검사가 모두 끝나는 것은 아닙니다. 사용한다면 @ConfigurationPropertiesScan 또는 @EnableConfigurationProperties로 등록하고 검증에는 Validation 의존성과 @Validated·제약 조건을 함께 구성합니다. 이번 세션에서는 설정 객체를 추가할 만큼 요구가 없으므로 포트 변경으로 외부 설정을 경험합니다.

세션 실습과 완료 기준

권장 90분: 생성·실행 20분, 세 파일 연결 30분, 변경·오류 분석 25분, 리뷰 15분입니다.

  1. 가상 회원 두 명을 반환하고 JSON의 필드 이름을 확인합니다.
  2. MemberService의 @Service를 잠시 제거해 시작 오류를 읽은 뒤 복구합니다.
  3. Controller를 스캔 범위 밖으로 옮기면 왜 경로가 등록되지 않는지 설명합니다. 실제 파일을 옮겼다면 원위치 후 검사합니다.
  4. ./gradlew test를 실행하고 기본 context 테스트만으로 API 응답 내용까지 확인한 것은 아니라는 점을 기록합니다.

완료 기준: Bean을 누가 만들고 전달하는지 설명하고 실행 명령·포트·요청 주소·실제 JSON을 README에 기록합니다. 서버가 뜬다는 사실과 기능 검증을 구별합니다.

더 읽어보기

연결된 PBL 미션과 VOD

주차·미션참고 VOD 범위
6주 · Spring Boot 전환Spring Boot 실습 3장

6–10주의 팝오버에는 Spring Boot 실습 강의명·장만 있고 직접 강좌 URL이 없다. 해당 미션의 참고 VOD 안내를 사용한다. 10주 VOD의 프론트 예제는 SvelteKit이며 React 전환을 필수로 요구하지 않는다.