Servlet과 Spring MVC
1. 서블릿이란?
처음 웹서버는 클라이언트 요청에 대해서 정적인 페이지로만 응답이 가능했습니다.
이후에는 웹 서버에 프로그램을 붙여서 동적인 페이지를 생성하기 시작했는데 서블릿도 동적인 페이지를 만들기 위해 웹서버에 붙이는 프로그램 중 하나 입니다.
한줄로 말하자면, 서블릿은 동적 페이지를 만드는데 사용되는 서버 프로그램 입니다.
사용하는 이유
위는 간단한 HTTP 요청과 응답입니다.
만약 개발자들이 위와 같은 요청 텍스트를 직접 해석하고 처리해서, 다시 규약에 맞게 응답 텍스트를 만들어 보내야 한다면 매우 번거로울 것입니다.
서블릿은 이러한 과정을 대신 처리해주도록 구현되어 있어 개발자들은 실질적으로 주가 되는 비즈니스 로직에 집중할 수 있게 됩니다.
2. 서블릿 컨테이너와 서블릿이 호출되는 과정
- 요청이 들어오면 Servlet Request / Servlet Response 객체 생성합니다.
- 설정 파일을 참고하여 매핑할 Servlet을 확인합니다.
- 해당 서블릿 인스턴스가 서블릿 컨테이너에 존재하는지 확인하고 있으면 가져다 사용하고, 없으면 생성합니다.
- Servlet 컨테이너에 스레드를 생성하고 res, req를 인자로 service를 실행합니다.
- 응답을 처리한 뒤 Request, Response 객체를 소멸시키고 끝이 납니다.
서블릿은 컨테이너에서 싱글톤으로 관리되기 때문에 요청 이후에 소멸되지 않고, 다음에 같은 요청이 들어왔을 때 재사용됩니다.
여기까지 이해했다면 서블릿 컨테이너는 쉽게 정의할 수 있습니다.
서블릿 컨테이너는 서블릿의 생명주기를 관리하는 객체입니다.
서블릿을 생성하고 필요한 순간에 호출하고 적절한 시점에 소멸시키는 역할을 담당하는 것입니다.
3. 프론트 컨트롤러 패턴
프론트 컨트롤러 패턴 도입 전에 요청당 서블릿을 정해주는 곳에 비효율적인 부분이 있었습니다.
핸들러의 공통 로직이 매번 중복된다는 문제가 있었습니다. 또한, Url마다 Servlet을 생성하여 관리해줘야 했습니다.
프론트 컨트롤러 패턴은 앞단에서 서블릿을 만들어 공통 로직을 처리하도록 하는 패턴입니다.
Spring MVC도 프론트 컨트롤러 패턴을 따르고 모든 요청을 받는 전면 컨트롤러를 Dispatcher Servlet이라고 부릅니다.
즉, 서블릿을 하나만 두고 모든 요청을 다 받을 수 있도록 하는 것입니다.
프론트 컨트롤러 패턴 이전에는 요청마다 서블릿을 정의하고 요청을 수행할 때마다 매번 스레드를 생성했다면, 이제는 하나의 서블릿만 정의하고 이 서블릿이 모든 요청을 수행하게 됩니다.
4. Spring MVC
실제로 Spring MVC의 구조는 위와 같습니다.
- 핸들러 조회
- 핸들러 매핑을 통해 요청 URL에 매핑된 핸들러(컨트롤러)를 조회한다.
- 핸들러 어댑터 조회
- 핸들러를 실행할 수 있는 핸들러 어댑터를 조회한다.
- 핸들러 어댑터 실행
- 조회한 핸들러(컨트롤러)를 인자로 핸들러 어댑터에 넘겨서 핸들러를 실행시킨다.
- ModelAndView 반환
- 핸들러(컨트롤러)가 로직을 수행하고 반환하는 정보로 ModelAndView로 변환해서 반환한다.
- viewResolver 호출
- 적절한 viewResolver를 찾고 해당 viewResolver를 호출한다.
- View 반환
- viewResolver는 뷰의 논리 이름을 물리 이름으로 바꾸고, 랜더링 역할을 담당하는 뷰 객체를 반환한다.
- 뷰 랜더링
- 뷰를 통해서 뷰를 랜더링한다.
프론트 컨트롤러 패턴 적용 전보다 상당히 복잡한 구조를 가지게 되는데 실질적으로 개발자가 신경써야할 부분은 오른쪽의 빨간색 부분 핸들러(컨트롤러) 입니다.
왼쪽의 파란색 부분은 Dispatcher Servlet이 스프링 컨테이너로부터 주입을 받아서 사용하고 동작하게 됩니다.
스프링 컨테이너는 프로그램이 동작하는 동안 사용되는 자바 객체들을 프레임워크가 대신 보관하고 관리하는 역할을 합니다.
서블릿 웹 애플리케이션 컨텍스트는 웹 요청 처리 관련 객체들이 담겨있고, 루트 웹 애플리케이션 컨텍스트 안에는 웹 요청처리와 관련된 빈 외의 나머지 컴포넌트들(서비스, 레포지토리 관렬 객체들)이 관리 됩니다.
따라서, 스프링 컨테이너는 개발에 필요한 부분이나 디스패치 서블릿이 요청을 처리할 때, 필요한 부분을 알아서 주입해주는 것입니다.
5. 스프링으로 웹 요청을 처리한다는 것..
결국 스프링으로 웹 요청을 처리한다는 것은 스프링 MVC에서 제공하는 디스패치 서블릿과 웹 요청 처리 관련 구현체들을 사용할 수 있다는 이야기와 동시에 스프링 컨테이너, 즉 스프링 IoC를 사용해서 개발할 수 있다는 이야기 입니다.
최종적인 목적은 개발자에게 핸들러 즉, 개발할 때 집중해야하는 요청처리 로직들에만 집중할 수 있도록 하기 위함입니다.