스프링 부트 3가 어떤 구조인지, 그리고 어떤 과정을 통해 실행되는지 코드와 함께 살펴봅니다. 여기를 공부하면 스프링 부트 3가 어떤 구조로 이루어져 있고, 앞으로 프로젝트를 진행할 때 어떤 구조로 진행해야 하는지에 대한 감을 잡을 수 있을 겁니다.
총 2편입니다. 1편에서는 스프링 부트의 구조를 살펴보고, 2편에서는 스프링 부트 프로젝트를 조금 더 발전시키면서 앞서 언급한 각 계층의 코드를 추가해보겠습니다.
[Spring] 스프링 부트 3 구조 이해하기 ❶
스프링 부트 3를 학습하기 위한 환경 설정은 [환경 설치] 되기 《스프링 부트 3 백엔드 개발자 되기 (자바편)》 참고해주세요.
0. 그림으로 이해하는 프로젝트
본격적으로 스프링 부트 애플리케이션을 만들어 봅니다. 전체적인 구조를 설명하기 위해 웹 브라우저, 스프링 부트 애플리케이션, 각 클래스, 의존성 간의 관계를 표시했습니다. 이후 과정에서는 이 구조를 유지하며 목적에 맞도록 코드를 작성해나갈 것입니다.
그림을 보면 웹 브라우저의 요청이 있고, 이 요청을 TestController 클래스에서 받아 분기 처리하여 TestService 클래스에 다음 작업을 요청합니다. 요약하자면 TestController 클래스는 ‘어떤 요청’인지 판단하고, TestService 클래스는 ‘그 요청에 맞는 작업’을 실행합니다. Member 클래스, MemberRepository 클래스는 데이터베이스를 위한 클래스입니다. Member 클래스로 구현한 클래스를 MemberRepository 클래스가 실제 테이블과 연결하죠.
1. 스프링 부트 3 구조 살펴보기
스프링 부트는 다음 그림에서 보듯 각 계층이 양 옆의 계층과 통신하는 구조를 따릅니다. 여기서 계층이라는 단어가 조금 낯설게 느껴질 수 있는데요. 계층이라는 것은 각자의 역할과 책임이 있는 어떤 소프트웨어의 구성 요소를 의미합니다. 각 계층은 서로 소통할 수는 있지만 다른 계층에 직접 간섭하거나 영향을 미치지 않습니다.
1.1 카페와 빵집으로 이해하는 계층
예를 들어볼까요? 어떤 거리에 카페와 빵집이 있다고 생각해봅시다. 카페는 커피를, 빵집은 빵을 팔겠죠. 그런데 필요한 경우 협업 관계를 맺어 어떤 손님이 커피를 사면 빵을 할인해줄 수도 있습니다. 이것이 계층 간의 소통입니다. 하지만 빵집 알바생이 빵을 팔다 말고 카페에 가서 커피를 팔 수는 없죠. 즉, 계층은 서로 영향을 끼치지 못합니다. 이렇게 각 계층은 자신의 책임에 맞는 역할(커피 팔기, 빵 팔기)을 수행하며, 필요에 따라 소통(커피 사면 빵 할인)합니다. 스프링 부트에는 프레젠테이션, 비즈니스, 퍼시스턴스 계층이 있습니다. 이 계층이 서로 통신하며 프로그램을 구성하죠.
프레젠테이션 계층
HTTP 요청을 받고 이 요청을 비즈니스 계층으로 전송하는 역할을 합니다. 컨트롤러가 바로 프레젠테이션 계층 역할을 합니다. 컨트롤러는 앞서 살펴본 TestController 클래스와 같은 것을 말하는데요, 컨트롤러는 스프링 부트 내에 여러 개가 있을 수 있습니다.
비즈니스 계층
모든 비즈니스 로직을 처리합니다. 비즈니스 로직이란 서비스를 만들기 위한 로직을 말합니다. 쉽게 말해 웹 사이트에서 벌어지는 모든 작업, 이를테면 주문 서비스라고 한다면 주문 개수, 가격 등의 데이터를 처리하기 위한 로직, 주문 처리를 하다가 발생하는 예외 처리 로직, 주문을 받거나 취소하는 것 같이 프로세스를 구현하기 위한 로직 등을 생각하면 됩니다. 서비스가 비즈니스 계층의 역할을 합니다.
퍼시스턴스 계층
모든 데이터베이스 관련 로직을 처리합니다. 이 과정에서 데이터베이스에 접근하는 DAO 객체를 사용할 수도 있습니다. DAO는 데이터베이스 계층과 상호작용하기 위한 객체라고 이해하면 됩니다. 리포지터리가 퍼시스턴스 계층의 역할을 합니다.
사실 이 설명으로는 스프링 부트 구조가 잘 이해되지 않을 겁니다. 여러분이 꼭 알았으면 하는 건 계층은 개념의 영역이고 컨트롤러, 서비스, 리포지터리는 실제 구현을 위한 영역이라는 겁니다. 이 말도 코드를 수정하다 보면 차차 알게 될 겁니다. 우선 이 정도로 설명을 마치고 다음으로 넘어가보죠.
1.2 스프링 부트 프로젝트 디렉터리 구성하며 살펴보기
여기서는 스프링 부트 프로젝트 디렉터리를 구성하면서 살펴보겠습니다. 스프링 부트에는 정해진 프로젝트 구조가 없지만 추천 프로젝트 구조는 있습니다. 많은 개발자가 이 구조를 따르므로 우리도 이 구조를 따라 개발할 겁니다.
main
실제 코드를 작성하는 공간입니다. 프로젝트 실행에 필요한 소스 코드나 리소스 파일은 모두 이 폴더 안에 들어 있습니다.
test
프로젝트의 소스 코드를 테스트할 목적의 코드나 리소스 파일이 들어 있습니다.
build.gradle
빌드를 설정하는 파일입니다. 의존성이나 플러그인 설정 등과 같이 빌드에 필요한 설정을 할 때 사용합니다.
settings.gradle
빌드할 프로젝트의 정보를 설정하는 파일입니다.
1.3 main 디렉터리 구성하기
main 디렉터리를 펼치면 java와 resources로 구성되어 있습니다. 우리가 작성한 코드가 들어 있는 디렉터리는 main/java 디렉터리죠? main/resources/static 디렉터리에는 아직 환경 설치에서 페이지를 보여주기 위해 추가했던 index.html 파일만 들어있을 겁니다. 여기에 아직 추가하지 못했던 스프링 부트 프로젝트의 구성 요소를 하나씩 추가해보겠습니다.
01단계
먼저 HTML과 같은 뷰 관련 파일을 넣을 templates 디렉터리를 만듭니다. resources 디렉터리를 우클릭하고 [New → Directory]를 순서대로 누르고 templates 디렉터리를 만듭니다.
02단계
static 디렉터리는 JS, CSS, 이미지와 같은 정적 파일을 넣는 용도로 사용합니다. static 디렉터리는 0장에서 만들었기 때문에 별도의 생성은 하지 않고 설명만 하고 넘어가겠습니다.
03단계
마지막으로 스프링 부트 설정을 할 수 있는 application.yml 파일을 생성합니다. 이 파일은 스프링 부트 서버가 실행되면 자동으로 로딩되는 파일입니다. 데이터베이스의 설정 정보, 로깅 설정 정보 등이 들어갈 수도 있고, 직접 설정을 정의할 때 사용하기도 합니다. 앞으로 프로젝트를 진행하며 자주 사용할 파일이므로 잊지 말고 만드세요.
다음 2편에서는 스프링 부트 3 프로젝트 발전시켜보고, 요청-응답 과정 한 방에 이해해봅시다.
신선영
리멤버 백엔드 개발자. 하드 스킬과 소프트 스킬 역량을 강화하고자 부단히 공부하고 글로 남기는 백엔드 개발자입니다. 평일 기준 하루 평균 600뷰의 기술 블로그를 운영하고, 모교 학생을 대상으로 정기 세미나와 멘토링을 진행합니다. 구독자가 1,000명 정도 되는 사이드 프로젝트를 기획하고 개발하고 운영한 경험이 있습니다.
저자 블로그 shinsunyoung.tistory.com
저자 깃허브 github.com/shinsunyoung