-
초창기 어플리케이션 : 웹 서버에서 정적컨텐츠만 전달
- 사용자마다 다른 화면이 아닌 동일한 화면(HTML 등) 제공
- 이후 동적 화면의 필요성을 느껴 CGI 등장
-
CGI(Common Gate Interface) : 동적 데이터 제공을 위한 규약
- client 요청 -> 웹서버 -> CGI 구현체 요청 -> 동적 데이터를 웹서버에게 전달 -> client
-
CGI 문제점
- 모든 사용자 요청마다 Process 사용해서 요청 처리
- 같은 요청이라도 동일한 CGI 구현체를 생성
- 매번 객체를 생성하고 종료하는 작업은 필요없는 서버 리소스를 불필요하게 낭비하는 구조를 가짐
- 해결하기 위해 Servlet 등장
-
Servlet : Java진영에서 동적 데이터를 제공하기 위해 CGI를 기반으로 제작된 프로그램
- 위의 문제점 해결(
서버 부담 리소스 줄이고
보다 효율적으로 동적 데이터를 클라이언트에게 제공
)
- 각 요청에서 Process 생성 방식을 Thread로 변경
- 동일 요청 구현체 매번 생성 -> 싱글톤 패턴을 적용하여 재사용 하도록 구조 변경
-
Servlet을 사용하며 개발자가 얻는 이점
- HTTP : 개발자는 요청들을 처리해주는 메서드를 재정의하고 API를 사용한 뒤
요청받을 URL만 매핑을 해주면 비즈니스 로직을 작성하고 수행할 환경을 제공 받을 수 있음
- 파싱 -> 응답 (개발자가 파싱, 응답은 번거롭고 반복적 작업)
- 파싱 작업을 일일히 하지 않더라도 API를 통해 제공받을 수 있음
- HTTP Method 분기처리도 각 요청별 대신 처리
-
Servlet Container : Servlet 생성, 호출, 제거의 모든 작업들을 관리하며 생명주기 관리
-
init() : 생성
-
destroy() : 제거
클라이언트 요청이 오게 되면 서블릿 컨테이너는 해당 요청과 매핑된 서블릿을 찾는 과정 -> 서블릿이 생성되어있지 않다먼 서블릿 생성 및 작업 -> 작업이 종료된 서블릿은 소멸되지 않고 서블릿 컨테이너에서 관리됨
클라이언트 요청과 매핑되어 있는 서블릿이 이미 존재한다면 서블릿 컨테이너는 해당 서블릿을 호출하여 재사용하여 작업 수행
-
Servlet의 문제점
- 각 요청마다 서블릿이 1:1 매칭 -> 서블릿마다 공통 실행되는 로직이 매번 반복되서 생성되고 실행
- 만일 10개의 요청이 있다면 10개의 서블릿 필요
- 서블릿마다 공통되어 실행되는 로직이 매번 반복되서 생성되고 실행하게 됨
- Front Controller Pattern 등장 : Front 컨트롤러에 공통로직을 만들어 두고 뒷단에 각 요청별로 처리하는 로직을 찾아 전달하여 요청 수행
- 매 요청마다 각각의 서블릿을 사용하는 것이 아닌 하나의 서블릿을 통해 요청 수행
- 긱 서블릿마다 가지고 있는 중복 로직들을 Front Controller 단 한곳에서 사용하여 중복 로직을 제거하게 됨
-
front controller가 하는일?
- 클라이언트 - 서버 연결
- 각 요청에 맞는 컨트롤러를 매핑하여 정보 보관
- 요청이 들어오면 매핑 정보를 찾아 해당 컨트롤러 호출
- 전달할 결과를 생성
- 결과를 사용자에게 반환
- 프론트 컨트롤러가 수행하는 일이 너무 많음
- 이후 각 수행 역할별 상황 분리
- 클라이언트 요청을 Front Controller가 받음
- 요청별로 각각의 역할을 수행하는 핸들러를 찾기 위해 핸들러 검색 역할 분리
- Front Controller는 객체를 만들어 요청의 정보를 넘기고 전달을 받을 모델까지 함께 넘김
- 서블릿 객체가 컨트롤러 매개변수로 전달되는 것이 아닌 자바 객체가 전달됨 -> 컨트롤러가 서블릿에 종속적인 문제 해결
- Front Controller로 넘어온 전달한 뷰의 이름에 대해 viewResolver를 객체를 통해 원본 view의 URI를 알아낸 후 CumtomView에게 렌더링 역할을 부여하여 역할을 분리하면 하나의 웹 요청이 끝남
-
Spring Web MVC : 위의 과정을 거쳐 만든 프레임워크
- FrontController -> Dispatcher Servlet으로 이름 변경
- Controller 또는 Handler를 호출하기 전에 중간에 어뎁터 역할을 해주는 Handler Adapter를 도입하여 다양한 종류의 핸들러를 호출할 수 있는 기능을 추가하여 보다 확장성 있는 기능이 개발되도록 변경
-
DispatcherServlet : 웹 요청 시 필요한 부분들을 알아서 주입하는 구조로 웹 요청이 동작함
- Servlet WebApplicationContext : 웹 요청을 담당하는 객체들이 들어가서 관리
- Controllers, View Resolvers, HandlerMapping
- Root WebApplicationContext : 서비스 계층, Repository 등 웹환경에 독립적인 빈이라는 것들이 들어가서 관리
-
즉 설정만 잘 작성하고, 등록해주면 그 설정대로 생성된 객체가 스프링 컨테이너 내부에서 관리되고 필요한 부분에 주입을 받아서 Dispatcher Servlet이 스스로 사용될 수 있음
-
Spring Web MVC가 가져다 주는 이점을 사용하면서 비즈니스 로직에 집중할 수 있다.