웹 프로그래밍/[ Spring ]

[ Spring ] 06. Spring MVC Framework와 Dispatcher-Servlet

kim.svadoz 2021. 6. 30. 16:42
728x90
반응형

Spring MVC


MVC 패턴을 적용한 Spring framework

Spring에는 개발자들이 일반적으로 사용할만한 기능과 운영 방식들이 편리하게 정의되어 있다.

Spring MVC에는 스프링이 제공하는 모든 기능을 잘 활용하기 위해서 스프링이 내가 작성한 자바 bean(객체)을 관리할 수있도록 해야 한다.

Spring Framework 내부에는 IOC 컨테이너가 존재해 내가 등록한 bean(객체)을 생성하고 관리해준다. -> 결합도(Coupling)을 낮출 수 있게 된다.

이를 위해 Dispatcher Servlet 이라는 Front-Controller 패턴의 Servlet을 가장 앞단에 둬서 컨테이너로 들어오는 모든 요청을 적절한 세부 컨트롤러로 작업을 위임해준다.

구성

  • DispatcherServlet
    • 클라이언트의 모든 요청을 처리하기 위해 첫 번째로 실행되는 서블릿
    • Dispatcher가 받은 요청은 HandlerMapping으로 넘어간다.
  • HandlerMapping
    • 클라이언트가 요청한 path를 분석해 어떤 컨트롤러를 실행해야 하는지 찾아서 DispatcherServlet으로 넘겨주는 객체
  • Controller
    • 클라이언트의 요청을 처리하는 객체
    • DAO의 메소드를 호출하는 기능을 정의
  • ModelAndView
    • Controller에서 DAO의 메소드를 실행결과로 만들어진 데이터에 대한 정보나 응답할 View에 대한 정보를 갖고 있는 객체
  • ViewResolver
    • ModelAndView에서 저장된 view의 정보를 이용해서 실제 어떤 view를 실행해야 하는지 정보를 넘겨주는 객체

스프링 MVC를 구축하면, 위 클래스 들이 자동으로 실행되며 일처리를 한다.

필요에 따라 ViewResolver나 HandlerMapping 객체를 다양하게 등록하고 사용할 수 있다.

Dispatcher-Servlet

서블릿 컨테이너에서 HTTP 프로토콜을 통해 들어오는 모든 요청을 프레젠테이션 계층의 제일 앞에 둬서 중앙집중식으로 처리해주는 프론트 컨트롤러(Front Controller)

클라이언트로부터 어떠한 요청이 오면 Tomcat과 같은 서블릿컨테이너가 요청을 받는 데, 이 때 제일 앞에서 서버로 들어오는 모든 요청을 처리하는 Front Controller를 Spring에서 정의하였고, 이를 Dispatcher-Servlet이라고 한다.

그래서 공통처리 작업을 DispatcherServlet이 처리한 후 적절한 세부 컨트롤러로 작업을 위임해준다.

물론 Dispathcer-Servlet이 처리하는 URL 패턴을 지정 해줘야 하는데 일반적으로 /*.do와 같이 /로 시작하며 .do로 끝나는 URL패턴에 대해서 처리하라고 지정되어 있다.

흐름 & 장점

Spring MVC는 Dispatcher-Servlet이 등장함에 따라 web.xml의 역할을 상당히 축소시켜주었다.

기존에는 모든 서블릿에 대해 URL Mapping을 활용하기 위해 web.xml에 모두 등록해줘야 했지만, dispatcher-servlet이 해당 어플리케이션으로 들어오는 모든 요청을 핸들링해주면서 작업을 상당히 편리하게 할 수 있게 되었다.

그리고 이 서블릿을 이용한다면 MVC 역시 사용할 수 있게 되어 좋다.

image-20210609150000076

위 그림과 같이 Dispatcher Servlet이 모든 요청을 Controller로 넘겨주는 방식으 효율적으로 보이나, 모든 요청을 처리하다 보니 이미지나 HTML 파일을 불러오는 요청마저 전부 Controller로 넘겨버린다.

게다가, .jsp 파일 안의 Javascript나 StyleCSS 파일들에 대한 요청들까지도 모두 디스패처서블릿이 가로채는 까닭에 자원을 불러오지 못하는 상황도 발생할 수 있다.

이에 대한 해결책 두 가지가 있다.

첫 째로, 클라이언트의 요청을 2가지로 분리하여 구분하는 것이다.

  1. /appsURL로 접근하면 Dispatcher Serlvet이 담당한다.
  2. /resourcesURL로 접근하면 Dispatcher Servlet이 컨트롤할 수 없으므로 담당하지 않는다.

이러한 방식은 괜찮지만 상당히 코드가 지저분해지며 모든 요청에 대해 저런 prefix URL을 붙여주기 때문에 직관적인 설계가 될 수 없다.

두번째 방법으로 모든 요청을 컨트롤러에 등록하는 것인데, 이는 상당히 무식한 방법이다.

Spring은 이러한 문제들을 해결함과 동시에 편리한 방법을 제공해주는데, 바로 <mvc:resources />를 이용한 방법이다. 이것은 만약 디스패처 서블릿에 해당 요청에 대한 컨트롤러를 찾을 수 없는 경우, 2차적으로 설정된 경로에서 요청을 탐색하여 자원을 찾아내는 것이다.

이렇게 영역을 분리하면 효율적인 리소스 관리를 지원할 뿐 아니라 추후에 확장을 용이하게 해준다는 장점이 있다.

참조 : https://mangkyu.tistory.com/18?category=761302

728x90
반응형