Chat 상우

spring Dispatcher Servlet 구조 및 동작원리 본문

Framework/spring

spring Dispatcher Servlet 구조 및 동작원리

chat-rilla 2023. 12. 7. 21:41

안녕하세요 it강사 chat 상우입니다.

Spring Dispatcher Servlet의 구조 및 동작 원리의 대한 개념 중 오류가 있는 부분은 피드백 부탁드립니다.

 

 1. Dispatcher Servlet(Spring)


Spring Dispatcher Servlet 개요

Dispatcher Servlet은 Spring Framework에서 중요한 역할을 하는 클래스 중 하나로 모든 Http 요청을 filter 이후 가장 먼저 받아 적합한 컨트롤러에 위임을 해주는 프론트 컨트롤러(Front Controller)이다. 이러한 방식의 디자인 패턴을 프론트 컨트롤러 패턴이라고 부른다.

@Controller 어노테이션을 사용하게 되면 Servlet을 상속하고 특정한 인터페이스를 구현하여 만들어지게 되며 추상화되고 유연한 방식으로 구현이 되어 있어 Http 요청을 처리하고 비즈니스 로직을 실행한 후에 뷰(view)로 결과를 전달하여 클라이언트에게 응답하게 된다.

 

Dispatcher Servlet이 등장하기 이전 web.XML(배포 서술자)에 모든 서블릿에 URL 대응을 해야 하는 번거로움이 존재하였다. 그러나 Dispatcher-servlet이 해당 애플리케이션으로 들어오는 모든 요청을 핸들링하고 공통 작업을 처리하게 되면서 개발자의 부담이 상당히 줄어들게 되었다. 그러나 이러한 방식의 요청을 이용하면서 약간의 문제가 발생하였는데 이는 Static Resources(정적 자원)에 대한 요청도 가로챈다는 것이다. 이러한 문제를 해결하기 위해 다음과 같은 방법을 지원한다.

 

  1. 정적 리소스 요청을 별도로 정의하고 핸들러로 등록하기
  2. Dispacher Servlet이 요청을 처리할 컨트롤러를 찾고, 요청에 대한 컨트롤러가 없는 경우 2차적으로 설정된 자원(Resource) 경로를 탐색하는 방식
// 정적 리소스 등록
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**")
                .addResourceLocations("/static/");
    }
}

 


Dispatcher Servlet의 역할

  1. Http 요청 처리 및 분배 : 클라이언트의 모든 HTTP 요청을 받아들이고, 요청된 URL을 분석하여 적절한 핸들러에게 전달하게 된다. 요청된 URL을 기반으로 적합한 컨트롤러로 작업을 전달한다.

  2. 핸들러 매핑과 실행 : DisPatcherServlet은 핸들러 매핑(Handler Mapping)을 사용하여 요청된 URL에 맞는 컨트롤러를 찾으며 이후 해당 컨트롤러를 실행하여 요청을 처리하게 된다.

  3. 뷰 리졸버와 뷰 전달 : 요청을 처리한 후, DispatcherServlet은 뷰 리졸버(View Resolver)를 사용하여 해당하는 뷰를 결정하고, 뷰를 실행하여 클라이언트에게 응답 결과를 생성한다.

  4. 전체적인 웹 애플리케이션의 흐름 제어 : Spring MVC에서 DispatcherServlet은 전체적인 웹 애플리케이션의 흐름을 제어하며, 애플리케이션 내의 요청 처리 과정을 관리한다.

Dispatcher Servlet의 동작 방식

사용자의 요청을 가장 앞 단에서 처리하는 Dispatcher Servlet은 사용자의 요청에 해당하는 controller를 매칭하여 요청을 처리하고 응답하는 과정의 내용이다.

dispatcher servlet 동작흐름

  1. 클라이언트의 HTTP 요청을 받는다.
  2. 사용자의 요청을 Handler Mapping으로 위임하여 들어오는 요청에 해당하는 URL에 매핑된 컨트롤러를 탐색한다.
  3. 2번에서 반환된 값이 있는 경우 해당 컨트롤러를 호출할 수 있는 HandlerAdapter에 요청을 전달한다.
  4. HandlerAdapter 에서 해당 컨트롤러를 호출한다.
  5. 컨트롤러에서 처리된 결과를 Model에 설정하여 뷰의 이름을 반환한다.
  6. Dispatcher Servlet은 5번에서 전달된 View를 View Resolver에 전달하고 해당하는 View 개체를 찾아 반환한다.
  7. 6번에서 반환된 View에 model의 값을 전달하고 화면 표시를 요청한다. 만약 전달된 Model의 값이 null이면 페이지를 그대로 사용하고 Model의 데이터가 존재하는 경우 렌더링 한다.
  8. 응답받은 View의 결과를 클라이언트에게 응답을 한다.

Dispatcher Servlet 구현 클래스 역할

디스패처 서블릿에서 각 단계별로 요청을 처리하는 과정을 상세히 정리하고자 controller 이후의 값은 생략하고 설명을 진행하고자 한다.

servlet 구조

  1. Web Context
    Web Context란 웹 애플리케이션이 실행되는 환경을 의미하며 주로 웹 애플리케이션의 설정과 구성 및 리소스, 빈들의 생명주기를 관리하는 컨테이너를 의미한다.

  2. Spring context
    Spring이 제공하는 IoC (Inversion of Control) 컨테이너를 의미한다. 이 컨테이너는 애플리케이션의 객체들을 생성하고, 관리하며, 필요한 곳에서 의존성을 주입한다.

  3. Filter
    디스패처 서블릿에 요청이 전달되기 전과 후에 해당 url에 매핑되는 모든 요청에 실행해야 하는 작업을 설정할 수 있는 기능을 제공한다. 이는 스프링에서 관리되는 것이 아닌 was(웹 컨테이너)에서 관리가 된다. 보통 보안과 관련된 작업을 수행하거나 모든 요청에 대한 로그 및 검사와 같은 spring과 분리되어 사용하는 기능을 수행한다.

  4. Dispatcher Servlet
    사용자의 요청을 가장 먼저 받는 해당 서블릿으로 과거 서블릿은 해당 URL 요청에 매칭되는 서블릿이 로직을 처리하였으나 이는 공통 로직이 매번 서블릿마다 중복이 되어 처리되기 때문에 중복 코드의 발생이 존재한다.
    이를 개선하기 위해 Spring에서는 Dispatcher Servlet에서 가장 먼저 모든 요청을 수행하고 처리하는 중앙 집중방식인 프론트 컨트롤러 패턴을 적용하여 이러한 불편함을 줄이게 되었다.

  5. interceptor
    filter는 웹 컨테이너에서 관리가 되는 것이라면 interceptor의 경우 spring이 제공하는 기술로 디스패처 서블릿이 컨트롤러를 호출하기 전과 후에 요청을 가로채서 추가 작업을 처리하는 기능을 제공한다.
    디스패처 서블릿에서 핸들러 매핑에 적합한 컨트롤러를 찾도록 요청을 하게 되면 그 결과를 바탕으로 실행 체인(HandlerExecutionChain)을 돌려주게 되는데 이 체인에 인터셉터가 등록되어 있으면 인터셉터들을 거쳐서 컨트롤러를 호출하게 된다.

  6. Handler Mapping
    Dispathcer Servlet이 요청받으면 해당 요청을 처리한 핸들러를 찾기 위해서 Handler Mapping에 요청을 전달하여 요청을 처리할 핸들러(컨트롤러)를 찾게 되는데 어느 컨트롤러가 요청을 처리할 수 있는지를 식별하는 것이 Handler Mapping이다.

  7. HandlerAdapter
    Handler Mapping을 통해 요청을 처리할 핸들러를 찾았다면 Dispathcer Servlet은 이를 호출할 수 있는 기능을 가진 HandlerAdapter 에게 요청을 위임하게 된다. 우리가 여기서 생각해 봐야 하는 것은 Dispatcher Servlet은 요청을 중계하는 중계자 역할을 하고 있다는 것이다. 이러한 이유는 스프링은 오랜 역사를 가진 프레임 워크로 계속 발전이 되어오면서 프로그램의 구현 방식이 다양해지고 있으므로 직접 호출을 하게 되면 프로그램의 결합 도가 올라가게 되면서 유지보수에 어려움을 겪게 될 것이다. 그러한 이유로 중간에 인터페이스를 두어 별도의 구현체를 통해 작업을 중계하게 되는 것이다.

  8. ViewResolver
    Controller의 요청 수행 후 Dispathcer Servlet의 요청 결과에 View에 이름이 반환되면 ViewResolver는 전달받은 뷰 이름과 실제 뷰 오브젝트를 매핑하고 해석하는 역할을 담당한다. 주로 Spring MVC에서 컨트롤러가 반환한 뷰 이름을 실제로 렌더링할 뷰로 해석하는 데 사용한다.

  9. View
    컨트롤러에서 반환된 값이 일반 데이터라면 view를 전달하는 과정은 생략되고 값이 전달되지만, view Name이 전달되는 경우 ViewResolver가 적절한 화면을 전달하게 되며 이때 Model의 값이 null이면 페이지를 그대로 사용하고 Model의 데이터가 존재하는 경우 렌더링 하여 응답하게 된다.

'Framework > spring' 카테고리의 다른 글

Spring boot 3.0.0 AND 3.2.0 Mybatis 연동 문제  (1) 2023.11.26