ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • DispatcherServlet에서 요청을 처리하는 과정
    spring/core 2021. 4. 5. 12:48

    배경

    추상적으로 이건 이렇게 되고 그 다음 이렇게 돼를 아는 건 중요하지만, 좀 더 시간이 지나면 이 과정을 코드로 이해해볼 필요가 있다. 아키텍처를 코드레벨로 이해하는 건 굉장한 기반 지식이 되기 때문이다^^.

     

     

    추상적인 DispatcherServlet의 요청 처리 과정

     

    Filter를 거친 요청은 최종적으로 DispatcherServlet에서 처리한다. 이때부터 과정을 쭉 스캔해보자.

    1) 서블릿에 등록한 핸들러매핑을 순회하며 요청에 맞는 핸들러매핑을 찾아낸다.(요청을 수행할 클래스)

    2) 핸들러매핑을 찾는 똑같은 프로세스로 핸들러어댑터를 찾는다(어댑터 패턴을 위해)

    3) 어댑터를 이용해 핸들러매핑(클래스의 메서드)를 수행한다

     

     

    코드를 통해 눈으로 살펴보자

     

    일단 그 이전 처리를 아주 간단하게 정리하면 DispatcherServlet은 FrameworkServlet를 상속한 뒤 추상 메서드인 doService()를 구현한 형태이다(템플릿 메서드 패턴). 이때 doService()에서 간단한 확인 작업을 마친 뒤 doDispatcher()를 호출하고 그 안에서 본격적인 작업이 시작된다.

     

    1) 서블릿에 등록한 핸들러매핑을 순회하며 요청에 맞는 핸들러 매핑을 찾아낸다

    this.handlerMappings에 담겨 있는 핸들러매핑을 선형으로 순회하며 현재 요청에 맞는 핸들러 매핑을 찾는다.

    기본적으로 등록되는 5개의 핸들러매핑이 있고 여기서 우리가 Controller로 등록한 클래스를 찾기 위해 각 핸들러 매핑이 제공하는 서비스를 확인해야 한다. 일반적으로 핸들러를 등록하는 방법인 @RequestMapping으로 등록하는 핸들러는 RequestMappingHandlerMapping의 mappingRegistry에 정보가 담겨 있다.

    이렇게 요청의 URL과 메서드를 분석해 가장 알맞은 핸들러매핑을 찾는다(수행할 메서드)

     

     

     

    2) 핸들러매핑을 연결할 핸들러 어댑터를 찾는다

    핸들러매핑마다 고유하게 메서드를 수행하는 방법을 갖고 있다. 이를 하나의 서블릿이 모두 처리하도록 하려면 각 핸들러매핑에게 작업을 위임할 수 있도록 적절한 어댑터를 필요로 한다. 이를 찾는 과정이고 RequestMappingHandlerMapping에 맞는 어댑터는 RequestMappingHandlerAdapter이다.

    어댑터를 찾고 인터셉터를 이용한 prehandle과정을 먼저 거친다.

    3) 어댑터를 이용해 핸들러 매핑을 수행한다

    여기서부터 약간 복잡하니 한 번 정리할 때 좀 더 디테일하게 정리한다.

    어댑터가 ha이고 ha의 handle()을 이용해 요청을 수행하는 모습니다. 요청, 응답, 수행할 메서드를 파라미터로 넘긴다.

     

     

    spring에서 정말 자주 나오는 템플릿 메서드 패턴이다. (현재 클래스는 AbstractHandlerMethodAdaptor)

     

     

    위 클래스를 상속해 추상 메서드인 handleInternal을 구현한 RequestMappingHandlerAdapter에서 약간의 전처리 후

    실제 핸들러메서드를 수행하는 모습이다.

     

     

     

    invocableMethod에 여러 정보를 세팅하고 이제 진짜로 시작한다.

     

     

    getMethodArgumentValues()를 이용해 내부적으로 파라미터를 바인딩하고 그 값을 전달한다.

     

     

     

    마치며

    깊게 파려고 하면 할수록 끝이 없는 것 같다. 나중에 좀 더 자세히 알아볼 기회가 있으면 좋겠다.

    우선은 이정도만?

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

    Spring Interceptor 사용 및 동작 정리  (0) 2021.05.14
    스프링 DI 방법  (0) 2021.05.06
    스프링 부트 자동설정 과정  (0) 2021.04.06
    HandlerMethodArgumentResolver 동작 원리  (0) 2021.03.08
    AOP 동작 원리  (0) 2021.03.06

    댓글

Designed by Tistory.