핸들러 매핑과 핸들러 어댑터가 어떤 것들이 어떻게 사용되는지 확인해보자.
Controller 인터페이스와 HttpRequestHandler 핸들러(컨트롤러)를 통해 예시를 들겠다.
Controller 인터페이스
- 과거 Spring에서 사용했던 인터페이스
- @Controller 어노테이션과는 전혀 다름
public interface Controller {
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
지난 게시글에서 살펴봤던 스프링 MVC 구조를 다시 살펴보자.
(글 순서: https://github.com/yeon-06/inflearnSpring/tree/master/mvc1 )
Controller 인터페이스를 구현한 Controller가 실행되려면 HandlerMapping, HandlerAdapter 두 가지가 필요하다.
네모 박스 안의 매핑과 어댑터들은 Spring boot가 자동으로 등록하는 것들로, 지금 설명에 필요한 부분만 명시했다.
HandlerMapping; 핸들러 매핑
- Handler Mapping에서 특정 Controller를 찾을 수 있어야 함
- ex: Spring bean의 이름으로 Handler를 찾을 수 있는 Handler Mapping 필요
0 = RequestMappingHandlerMapping // 애노테이션 기반의 컨트롤러인 @RequestMapping에서 사용
1 = BeanNameUrlHandlerMapping // 스프링 빈의 이름으로 핸들러를 찾기
HandlerAdapter; 핸들러 어댑터
- Handler Mapping을 통해 찾은 Handler를 실행할 수 있는 Handler Adapter가 필요
- ex: Controller 인터페이스를 실행할 수 있는 핸들러 어댑터를 찾고 실행해야 함
0 = RequestMappingHandlerAdapter // 애노테이션 기반의 컨트롤러인 @RequestMapping에서 사용
1 = HttpRequestHandlerAdapter // HttpRequestHandler 처리
2 = SimpleControllerHandlerAdapter // Controller 인터페이스 처리
간단한 예제를 통해 살펴보자.
@Component("/springmvc/old-controller")
public class OldController implements Controller{
@Override
public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse res) throws Exception {
System.out.println("OldController.handleRequest");
return null;
}
}
- 실행 여부만 확인하기 위해 반환값도 없애고 println만 실행
- @Component: 해당 컨트롤러를 /springmvc/old-controller라는 이름의 스프링 빈으로 등록
- bean의 이름으로 URL을 매핑
실행 순서
1. /springmvc/old-controller 경로로 접근
2. Handler Mapping으로 Handler 조회
- HandlerMapping을 순서대로 실행해 핸들러 찾기
- 스프링 bean 이름 그대로 찾아주는 핸들러인 BeanNameUrlHandlerMapping 실행 -> Handler인 OldController 반환
3. Handler Adapter 조회
- HandlerAdapter의 supports() 순서대로 호출
- SimpleControllerHandlerAdapter가 Controller 인터페이스 지원하므로 선택됨
4. Handler Adapter 실행
- DispatcherServlet이 조회한 SimpleControllerHandlerAdapter를 실행하며 Handler 정보도 함께 넘김
- SImpleControllerHandlerAdapter는 Handler인 OldController를 내부에서 실행 - > 결과 반환
HttpRequestHandler
- Servlet과 가장 유사한 형태의 핸들러
@Component("/springmvc/request-handler")
public class MyHttpRequestHandler implements HttpRequestHandler{
@Override
public void handleRequest (HttpServletRequest req, HttpServletResponse res) throws ServletException {
System.out.println("MyHttpRequestHandler.handleRequest");
}
}
실행 순서
1. /springmvc/request-handler 경로로 접근
2. Handler Mapping으로 Handler 조회
- HandlerMapping을 순서대로 실행해 핸들러 찾기
- 스프링 bean 이름 그대로 찾아주는 핸들러인 BeanNameUrlHandlerMapping 실행 -> Handler인 MyHttpRequestHandler 반환
3. Handler Adapter 조회
- HandlerAdapter의 supports() 순서대로 호출
- HttpRequestHandlerAdapter가 HttpRequestHandler 인터페이스 지원하므로 선택됨
4. Handler Adapter 실행
- DispatcherServlet이 조회한 HttpRequestHandlerAdapter를 실행하며 Handler 정보도 함께 넘김
- HttpRequestHandlerAdapter는 Handler인 MyHttpRequestHandler를 내부에서 실행 - > 결과 반환
본 게시글은 김영한 님의 '스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술' 강의를 구매 후 정리하기 위한 포스팅입니다.
내용을 임의로 추가, 수정, 삭제한 부분이 많으며 정확한 이해를 위해서 강의를 구매하시는 것을 추천 드립니다.
'Develop > Spring+JPA' 카테고리의 다른 글
[스프링 MVC] @Controller, @RequestMapping (0) | 2021.05.27 |
---|---|
[스프링 MVC] 뷰 리졸버 (0) | 2021.05.26 |
[스프링 MVC] 스프링 MVC 구조, DispatcherServlet (0) | 2021.05.24 |
[Spring] Path with "WEB-INF" or "META-INF" 에러 (2) | 2021.05.21 |
[Spring] Initializr로 스프링 부트 기반 프로젝트 생성 (0) | 2021.03.10 |