[Spring] Servlet과 Spring Web MVC

Jihyoung·2023년 3월 27일
2

Spring

목록 보기
2/5
post-thumbnail

요즘 개발하시는 분들은 아마 대체로 Spring Web MVC를 기반으로 하여 개발하고 있는 듯 하다.
나 역시 Spring Web MVC를 사용한다.
MVC의 간단한 개념에 대해서는 알고 있었지만, 이번 기회를 통해 어떻게 Spring Web MVC가 탄생하였는지 근본적인 이해를 통해 좀 더 확실하게 정리해보려 한다.

Java Servlet에서 어떤 과정을 통해서 흔히 사용하는 Spring Web MVC 프레임워크로 발전하게 되었는지 알아보자 🤩


초기 웹 어플리케이션

초기의 웹 어플리케이션은 HTML과 같은 정적인 데이터만을 제공했다. 정적 웹 페이지를 호출하는 과정은 아래와 같다.

  1. 클라이언트가 웹서버에 정보를 요청한다.
  2. 웹서버는 이미준비되어 있는 정보를 조회한다.
  3. 조회된 정보를 응답한다.
  4. 응답받은 데이터를 브라우저가 해석하여 사용자에게 보여준다.

하지만 이에 한계를 느껴 동적 컨텐츠를 제공하기 위해 CGI(Common Gate Interface)의 개념이 등장한다.


CGI(Common Gate Interface)


이후에는 동적인 데이터 제공을 위해 CGI가 등장하였다. CGI란 공통 게이트웨이 인터페이스(Common Gateway Interface)의 약어로, 웹서버와 외부 프로그램 사이에서 정보를 주고받는 방법이나 규약들을 말한다.
CGI 가 생긴 이후 동적 웹 페이지를 호출하는 과정은 다음과 같다.

  1. 클라이언트가 웹서버에 정보를 요청한다.
  2. 웹 서버는 CGI를 구현한 구현체에게 동적인 데이터를 요청한다.
  3. CGI는 이를 수행하여 클라이언트에게 제공한다.

그러나 CGI를 이용한 동적 컨텐츠 처리에는 몇 가지 문제점이 발생했다.

  • 모든 사용자 요청마다 프로세스를 사용하여 요청을 처리
    - 속도가 느리고 서버 메모리를 많이 차지
  • 페이지 로드 사이에 데이터가 메모리에 캐시될 수 없어 동일한 요청에도 CGI 객체를 반복해서 생성
    - 서버 리소스 낭비

이러한 문제점을 해결하기 위해 Servlet 이라는 개념이 등장하게 된다.


Servlet

Servlet은 동적 데이터 제공을 위해 CGI를 기반으로 제작된 프로그램이다.
앞서 CGI를 사용하면서 프로세스를 통해 처리하던 것을 스레드를 통해 처리하여 서버에서 많은 리소스를 소모하는 문제를 해결한다.
또한 동일한 요청을 반복해서 처리할때 객체를 계속 생성하던 문제를 Singleton 패턴 을 적용하여 구현체를 재사용 할 수 있도록 한다.

이로 인하여 서버의 부하를 줄여 동적 데이터를 처리할 수 있게 되었다.

Servlet Container

이러한 Servlet을 관리해주는 역할을 하는 것이 바로 Servlet Container 이다.

Servlet Container의 역할

1. 웹서버와의 통신 지원

서블릿 컨테이너는 서블릿과 웹서버가 손쉽게 통신할 수 있게 해주어, 소켓을 만들고 listen, accept 등을 API로 제공하여 복잡한 과정을 생략할 수 있게 해준다.

2. Servlet 생명주기(Life Cycle) 관리

서블릿 컨테이너는 서블릿의 탄생과 죽음을 관리한다.
1) 서블릿 클래스를 로딩하여 인스턴스화
2) 초기화 메소드를 호출
3) 요청이 들어오면 적절한 서블릿 메소드를 호출합니다.
4) 서블릿 소멸 시 Garbage Collection(가비지 컬렉션)을 진행

3. 멀티스레드 지원 및 관리

Servlet Container는 요청이 올 때 마다 새로운 자바 스레드를 하나 생성하고, HTTP 서비스 메소드를 실행하고 나면, 쓰레드는 자동으로 소멸된다.
기존에는 쓰레드를 관리해야 하지만 서버가 다중 스레드를 운영해 주기 때문에 쓰레드의 안정성에 대해서 걱정하지 않아도 된다.

Servlet Container 동작 과정

  1. 웹서버가 HTTP 요청을 받는다
  2. 웹서버는 요청을 서블릿 컨테이너로 전달합니다.
  3. 서블릿이 컨테이너에 없다면, 서블릿을 동적으로 생성하고 컨테이너의 주소 공간에 로드한다.
  4. 요청에 대한 작업이 종료되면 소멸되지 않고 서블릿 컨테이너 내에서 관리된다.
  5. 만일 서블릿이 컨테이너에 존재 한다면, 컨테이너가 해당 서블릿을 호출하여 HTTP 요청을 처리한다. (재사용)

그러나 Servlet은 각 요청에 대해 1대 1로 매핑되어 있었기 때문에 요청의 수만큼 존재하여 컨트롤러에서 공통으로 처리해야하는 로직이 중복되어 발생한다는 문제점이 있었다.

이를 해결하고자 Front Controller 가 등장하게 되었다.

Front Controller

Front Controller 이용 전Front Controller 이용 후

Front Controller를 통해 클라이언트의 요청을 받는 최 앞단에 컨트롤러를 하나 생성하고, 각 요청별로 처리하는 로직을 찾아 전달 할 수 있도록 하였다. 이를 통해 하나의 Servlet을 통해 요청을 수행할 수 있게 되었으며, 중복 요청들을 Front Controller 한 곳에서 사용하기 때문에 중복 로직을 제거한다는 장점을 가지게 되었다.

이러한 과정을 바탕으로 만들어진 프레임워크가 바로 우리가 흔히 사용하는 Spring Web MVC 이다.

Spring Web MVC

Spring Web MVC에서는 Front Controller의 역할을 Dispatch Servlet이 담당하게 되었고, 컨트롤러나 핸들러를 호출하기 전에 Handler Adapter라는 기능을 통해 다양한 핸들러를 호출할 수 있는 기능을 추가하여 응용하기 쉬운 형태로 변경되었다.

이러한 과정을 거쳐 우리가 흔히 사용하는 Spring Web MVC 가 탄생하게 된 것이다.


마치며

Spring을 사용하여 개발하면서 각종 기능들을 제공받아 편리함을 항상 느끼고 있었는데 왜 이러한 기능들이 탄생하게 되었는지 발전 과정에 대해 이해해보면서 쓰임새를 더 정확하게 알 수 있었던것 같다.
프레임워크가 개발을 편리하게 해주지만 항상 그를 위한 근본적인 부분을 파악하고 있어야 좀 더 디테일한 부분까지 캐치할 수 있을거 같다!
앞으로도 이를 위해 공부하고 기록하는 시간을 가져야겠다😀

profile
로그를 생활화

3개의 댓글

comment-user-thumbnail
2023년 4월 3일

혹시 Spring.io에 접속해본적이 있으신가요 ?
Spring에서 최근 가장 강조하는 기술은 microservice와 Reactive 입니다.
이 둘은 전통적인 MVC stack이 아닌 Webflux stack입니다.
여기에 대해서도 학습하시면 좋은 기회가 될 거 같아요.

정리도 깔끔하고 저도 기분좋게 복습할 수 있는 글이라 좋았습니다

답글 달기
comment-user-thumbnail
2023년 4월 3일

깔끔한 정리!!👏👏👏 이해가 쏙쏙 됩니다

답글 달기
comment-user-thumbnail
2023년 4월 29일

각각에 대해서 두루뭉술하게 알고있었는데 확실하게 연결시켜서 정리해주시니 이해가 잘 되네요!
덕분에 저도 배워갑니다. 좋은 글 감사해요 : >

답글 달기