Spring MVC를 알아보기 전에 먼저 MVC 패턴에 대해 알아보아야 합니다.
초창기 웹은 상대적으로 복잡하지 않은 구조를 갖기 떄문에 하나의 소스 코드 파일 내에 뷰(HTML), 로직(Java) 등이 혼재되어 있었습니다. 다음 서블릿 코드를 보면 하나의 소스 코드 파일에 뷰와 비즈니스 로직이 혼재해 있음을 볼 수 있습니다.
소스 코드 파일 수는 줄겠지만 뷰와 비즈니스 로직이 섞여있어서 유지보수 측면에서 너무 많은 리소스를 잡아먹었습니다. 이러한 문제점을 해결하고자 소스 코드의 책임 분야를 Model, View, Controller 세 개로 나누고 세 책임 소재의 앞글자를 따와 MVC 패턴이라고 부르게 되었습니다.
Model
모델은 애플리케이션의 정보, 데이터(DB, 변수 등)와 그 정보/데이터를 가공하는 로직이 포함된 컴포넌트들을 의미합니다.
View
뷰는 사용자에게 표시되는 화면 영역을 담당합니다. 사용자가 직접 조작을 통해 상호작용할 수 있는 메뉴를 제공하고 요청한 결과를 표시해주는 컴포넌트들을 의미합니다.
Controller
컨트롤러는 Model-View 간을 연결해줍니다. 이 연결 과정에서 사용자의 요청을 받고 모델에게 데이터 요청/처리를 시켜 그 결과를 View로 전달합니다.
정말 단순하게 표현하자면 검색창이 있습니다.
1. 사용자가 검색창에 단어를 넣고 검색 버튼을 누른다. (Controller)
2. 해당 단어가 포함된 결과는 DB 등에서 검색 결과를 찾는다. (Model)
3. 검색 결과를 사용자에게 보여준다. (View)
이런식으로 각 컴포넌트의 책임 소재를 명확히하여 유지보수 및 관리를 쉽게할 수 있도록 만들어줍니다.
Spring MVC는 스프링 프레임워크에서 MVC 패턴을 개발자가 쉽게 사용할 수 있도록 구현된 프레임워크입니다.
가장 큰 특징은 DispatcherServlet라는 Front Controller 패턴을 이용한다는 점 입니다.
Front Controller 패턴은 들어오는 모든 요청을 한 컨트롤러가 가장 선두에서 먼저 받아서 각 요청을 적절한 컨트롤러로 위임시키는 역할을 합니다.
이미지 출처
Spring MVC에서는 이 Front Controller를 DispatcherServlet이라는 컴포넌트가 수행하고 있습니다.
Spring Framework에서 요청이 들어오면 DispatcherServlet이 가장 먼저 받습니다. 그리고 공통된 처리 로직을 제공해 처리한 후 HandlerMapping에게 들어온 요청을 어떤 컨트롤러가 처리할 지 매핑합니다.
DispatcherServlet은HandlerMapping에게 요청 URL을 전달하고,HandlerMapping은@Controller등의 정보들을 탐색한 뒤 요청을 처리할 컨트롤러(= Handler) 객체를 반환합니다.이후 매핑된 컨트롤러에게 요청 처리를 시키기 위해
HandlerAdapter를 찾아서 컨트롤러가 요청을 처리할 수 있게 연결해줍니다.
이 연결 과정을 거치는 이유는 컨트롤러를 정의하는 방식이 다양하기 때문입니다. 주로@Controller어노테이션 방식을 사용하긴 하나 인터페이스 등을 사용해서도 정의할 수도 있습니다. 그래서 정의 방식에 맞는 Adapter가 선택되게 됩니다.그리고 컨트롤러 내의 요청을 처리할 메소드를 호출하는 것 또한
HandlerAdapter가 호출하게 됩니다. 이 호출 후 실행 과정에서@Service, @Repository등이 호출되기도 합니다.
매핑된 Controller가 요청을 처리(모델에 의해)한 뒤 ModelAndView 객체를 반환합니다. 이후 DispatcherServlet는 ViewResolver를 사용해서 뷰를 렌더링하고 응답으로 반환해 클라이언트에게 보여주게 됩니다.
이 과정에서 스프링 개발자는 Controller, View (필요 시 Service, Repository 등)만을 작성합니다. DispatcherServlet, HandlerMapping, HandlerAdapter, ViewResolver 등은 스프링 프레임워크가 자동으로 처리해줍니다. 필요에 따라서 설정만 변경하기만 하면 됩니다.