Spring Boot 프레임워크는, Spring 프레임워크의 하위 프로젝트 입니다. 웹 서비스를 제공하는데 많이 사용되는 Web Application Framework 이기도 합니다. 저희가 만든 Spring Boot 프로젝트가 사용자의 브라우저 까지 전달되는 과정은 어떻게 진행되는지 살펴보도록 합시다.
일반적인 웹 서비스의 배포 구조
저희가 사용하는 인터넷 브라우저는 실제로 인터넷 상에서 통신을 하여 저희에게 보여줄 HTML 문서를 해석하는 역할을 합니다. 이말은 이 HTML을 전달하기 위한 물리적 컴퓨터가 전세계 어딘가에 있어야 한다는 이야기 입니다. 이 컴퓨터를 찾기 위한 IP와 도메인에 대해서는 DNS에 대해서 공부해 봅시다. 저희가 만드는 Spring Boot Application 역시 이 인터넷 상의 물리적 컴퓨터, 서버에 배포되어야 합니다.
인터넷 상의 서버는 IP를 통해 도달하게 됩니다. IP를 가지고 특정 신호를 보내게 되면, 서버는 요청의 형식(HTTP, HTTPS) 또는 요청 주소를 통해 정확히 어떤 프로세스로 요청을 보낼지를 결정하게 됩니다. 이 끝에는 일반적으로 Web Server가 존재하게 됩니다. 여기서 사용하는 서버 컴퓨터의 성능이나, 서비스의 성격에 따라 내부는 전혀 다르게 구성할 수 있습니다.
Spring Framework의 경우 산출물이 WAR 파일의 형태로 나오게 됩니다. 이는 Tomcat을 비롯한 Jakarta Servlet Container를 제공하는 WAS를 통해 제공해야 한다는 의미입니다. Spring Boot 프로젝트는, 이때 필요한 Servlet Container를 프로젝트 내부에 내장하여, 단독으로 실행할 수 있는 Jar 파일로 산출물이 나올 수 있도록 진행된 프로젝트 입니다. 현재는 이를 단독으로 사용하거나, NGINX를 비롯한 다른 Web Server를 통해 서버를 구성하게 됩니다.
Java와 Jar
즉 Spring Boot Framework의 산출물은 JAR 파일로 나온다고 보면 됩니다.
JAR 파일은 Java ARchive의 약자입니다. Java로 작성, 컴파일된 Bytecode를 실행에 필요한 다양한 자원과 함깨 압축한, Java 명령어로 실행 가능한 파일을 부르는 명칭입니다.
왼쪽은 일반적인 Spring Boot 프로젝트 이며, 오른쪽은 해당 프로젝트를 이용해 만들어진 JAR 파일의 내용물입니다. 보면 알겠지만, 그 구조가 크게 다르지 않습니다. 개별 파일들의 확장자는 *.java 라는 소스코드에서, *.class 라는 Java Bytecode로 변환되었다는 점이 있습니다.
위 파일은 JAR파일에 함깨 포함되는 MANIFEST.MF 파일입니다. 이 파일에 작성된 내용이 어떤 Java Bytecode를 실행할지와 같은 정보가 저장되어 있습니다. 위의 파일을 보면 Main-Class와 Start-Class의 정의를 확인할 수 있습니다. 여기서 Main-Class는 Spring Boot 프로젝트의 기초 Entrypoint이며, Start-Class는 실행할 Spring Boot 프로젝트에 대한 내용입니다.
이런 JAR파일은 java 명령어를 통해서 실행할 수 있습니다. Spring Boot Framework의 산출물 역시 이러한 JAR 파일인 만큼, JDK를 설치한 저희들로선 얼마든지 실행할 수 있습니다.
Web Application 구조
기본적으로 Application을 개발하게 되는 경우, 그 내부 구조를 역할에 따라 분류를 달리하게 됩니다. 이를 사용자와 어느정도로 가까운지에 따라 계층을 이루게 되어, multi-tier 구조라고도 합니다. Web Application 뿐만 아니라, 대부분의 Application이라면 유사한 구조를 이루게 됩니다.
Presentation Layer의 경우 사용자와 직접적으로 맞닿는 부분을 부르게 됩니다. Web Application이라면 결국 인터넷 브라우저를 이용해 서비스에 접근하게 될 것입니다. 인터넷 브라우저는 결과적으로는 서버에서 보낸 HTML 문서를 해석하여 사용자에게 제공하는 것이니, Web Application의 HTML 구성같은 것을 생각할 수 있습니다.
Logic Layer의 경우 사용자의 입력에 대한 기능이 정의되며, 어떤 결과를 반환할지, 즉 전체적인 결정 과정(Business Logic)을 제공하기 위한 계층입니다. 전체적인 서비스의 관점에서는 이 계층이 저희가 배우는 Spring Boot가 맡게되는 부분이라고 생각할 수 있습니다.
Data Layer의 경우, 일반적인 Web Application에서 사용하게 될 데이터를 다루게 되는 계층을 의미하게 됩니다. Logic Layer에서 내린 결정은 흔히 Data Layer에 데이터를 저장하거나, Data Layer에서 데이터를 회수하는 형태로 진행되는 부분이 많습니다. MySQL을 비롯한 관계형 데이터베이스에 데이터를 적재하는 계층을 의미합니다.
Spring Boot의 Application은 들어온 요청을 기반으로, 어떤 HTML을 제공하거나, 특정 데이터에 대한 조작의 기능을 중계하는 등의 결정을 하는 역할을 하게 됩니다. 그리고 그 과정을 저희가 Java 언어를 이용해 다루게 되는 부분입니다.
Spring Application의 내부 구조를 살펴보면 위의 그림과 같습니다. HTTP 요청이라고 하는 일반적인 인터넷 브라우저에서 들어오는 요청을 처리하기 위한 DispatcherServlet이 존재합니다. 이 DispatcherServlet은 Spring Framework안에 구현된 부분입니다. 여기서는 저희가 작성한 코드를 기반으로 사용자의 요청을 분배하는 부분이 실제로 구현된 부분입니다.
DispatcherServlet 이후 사용자의 HTTP 요청은 재해석되어 다루기 편한 Java 코드의 형태로 Controller 로 전달됩니다. 여기서 Controller → Service → Repository 단계로 요청이 전달되는데, 이 부분은 개발자가 구성하여 역할을 나누는 부분이 됩니다. 마지막엔 Data Layer에 해당하는 Database와 소통하여 데이터를 다루고, 다시 DispatcherServlet으로 응답을 전달합니다. DispatcherServlet 은 돌아온 응답에 대하여, View Resolver 를 통해 HTML을 만들어 내거나, 데이터 응답을 있는 그대로 전달하게 됩니다.
즉 사용자의 요청이 들어오면,
1.
DispatcherServlet 이 들어온 요청을 처리하기 적합한 Controller 를 찾아내고,
2.
Controller 이하의 Application 구성이 응답을 만들어 내고
3.
DispatcherServlet 이 상황에 따라 응답을 반환한다.
a.
이때 ViewResolver 와 함깨 HTML 응답을 반환하거나,
b.
데이터를 표현을 다루기 위한 응답을 반환한다.
와 같은 과정으로 진행된다고 생각할 수 있습니다.
여기에 앞서 살펴보았던 Web Server 프로그램과 함깨 전체적인 웹 서비스의 구조를 이루게 됩니다.
Spring Boot는 전체 웹 서비스에서, Backend Server Application의 위치를 가지고 있습니다.