본문 바로가기

웹 개발(OLD)/Spring Framework(OLD)

Spring MVC 원리

-Spring MVC 원리


MVC 패턴을 spring 프레임워크 기반으로 구현한 모듈로써, 모든 웹 요청을 하나의 서블릿이 받아서 처리하는 방식의 Front Controller 패턴이다. 

즉, DispatcherServlet 이라는 Front Controller를 등록해 두고 공통적인 작업을 수행한 후 핸들러를 호출하는 방식으로 동작한다. 

Spring 기반의 애플리케이션은 ApplicationContext라고 불리는 IoC 컨테이너를 가지고 있는데 이를 이용해서 객체를 관리한다. 이를 이용하면 객체가 개발자의 코딩에 의해 생성되는 것이 아니라 IoC컨테이너에 의해서 생성되고 관리된다.(DI를 이용해서 미리 생성된 객체들을 IoC 컨테이너에 주입함으로써 실행 중에 객체들의 life-cycle을 관리할 수 있게 된다. 

Spring을 이용해 웹 애플리케이션을 만들면 기본적으로 WebApplicationContext를 이용한 IoC 컨테이너가 생성된다. 이때 WebApplicationContext는

부모컨텍스트<----자식컨텍스트의 계층구조를 가진다. 아래와 같이 web.xml에 각각의 컨텍스트를 설정하는 부분이 있다.


<web.xml 에서 부모 컨텍스트 설정 -> root-context.xml을 참고하여 만들어진다.>



<web.xml 에서 자식 컨텍스트 설정 -> servlet-context.xml을 참고하여 만들어진다.>



Ioc 컨테이너에서는 DI를 이용해서 객체를 찾을때 먼저 자신의 컨텍스트에서 찾은 후 없으면, 부모 컨텍스트 까지 찾는다. 

그래서 다음과 같이(root-context.xml의 일부 코드) 부모 컨텍스트에는 프로젝트에서 공통적으로 사용하는 객체와 Service, Repository 객체들을 설정하는 것이고, 



자식 컨텍스트(servlet-context.xml의 일부 코드)에는 View에서 사용하는 객체와 Controller 객체를 설정하는 것이다.



Spring을 이용해 웹 애플리케이션을 만들면 기본적으로 WebApplicationContext를 이용한 IoC 컨테이너가 생성된다고 했는데, 

이 WebApplicationContext 가 생성되면 root-context.xml 이나 servlet-context.xml 같은 각종 설정 정보를 읽고, 서비스를 할 준비를 한다. 여기서 클라이언트로 들어오는 요청을 최초로 받아서 처리할 대표 서블릿을 하나 생성하게 되는데 이게 DispatcherServlet이다. 즉, 클라이언트로부터의 요청을 핸들링할 준비가 된 것이다. 이제 DispatcherServlet는 클라이언트로 들어오는 요청마다 처리할 Controller Bean을 찾아서 전달하고, Controller가 처리한 결과를 적절한 View로 전달해 화면을 생성하도록 하여 응답을 처리하도록 한다.


아래 그림과 함께 DispatcherServlet 이 클라이언트로부터의 요청을 처리하는 과정을 살펴보자



1. 클라이언트의 요청을 받는다.

web.xml을 이용해 서블릿 컨테이너에 요청을 처리할 DispatcherServlet 을 설정해 두면 자식 ApplicationContext 가 생성되면서 요청을 받아서 처리할 수 있는 상태가 된다.

클라이언트로부터 요청이 들어오면 자식 ApplicationContext( servlet-context.xml ) 에 정의된 URL 패턴을 검사해 일치할 경우 Spring MVC 는 해당 요청을 가로채서 DispatcherServlet 으로 전달한다.

2. 전달된 요청을 Handler Mapping 전략으로 분석해서, 요청을 처리할 Controller 를 찾는다.

여러가지 Handler Mapping 전략이 있는데, 가장 많이 사용하는 것이 DefaultAnnotationHandlerMapping 이다. 이는, @RequestMapping 을 이용해서 Bean을 찾아내는 방식이다. 

아래 그림과 같이 컨트롤러 클래스를 구현할 때 @RequestMapping("/board/*") 처럼 매핑되는 URL을 명시하게 되는데 이 부분을 보고 클라이언트로부터의 요청을 처리할 컨트롤러를 찾는 것같다.


3. 찾아낸 Controller로 요청을 보내서 처리한다.

이때 한 컨트롤러내에 처리할 요청을 메소드 단위로 URL을 매핑하여 설계해놨으므로 적절한 메소드에서 해당 요청이 처리된다.

요청을 처리하고 난 결과를  DispatcherServlet 으로 리턴한다. 이때 처리 결과를 ModelAndView 형태의 객체에 담아서 처리한다.

ModelAndView 는 Model과 View 객체를 갖고 있는 객체이다. Model 객체는 처리 결과를 담고 있고, View 객체는 사용자에게 돌려줄 View 의 정보가 담겨있다. DispatcherServlet 은 View 객체를 이용해서 사용자에게 돌려줄 View타입을 찾아낸다.

4.  ModelAndView 정보를 이용해 ViewResolver 로 결과물을 생성할 View 를 검색한다. 

ViewResolver 는 Controller 에서 리턴된 View 객체를 이용해 결과화면을 구성할 View 를 검색하여 찾아내고, 해당 View 들은 Model 객체를 이용해 적절한 로직을 수행한다.


5,6.  검색된 View 타입으로 View 정보를 생성한 후 클라이언트에 응답한다.

ViewResolver 에 의해 적절한 View가 검색되면 ModelAndView 정보를 이용해 클라이언트에게 돌려줄 최정 정보가 생성된다. View 새엇ㅇ이 완료되면 결과를 클라이언트에게 내보낸다.