오봉이와 함께하는 개발 블로그
스프링 MVC 1 - 핸들러 매핑과 핸들러 어댑터 본문
핸들러 매핑과 핸들러 어댑터
핸들러 매핑과 핸들러 어댑터가 어떤 것들이 어떻게 사용되는지 알아보자.
Controller 인터페이스
과거 버전 스프링 컨트롤러
public interface Controller {
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
Controller 인터페이스는 @Controller과는 전혀 다르다.
간단하게 구현해보자.
@Component("/springmvc/old-controller")
public class OldController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("OldController.handleRequest");
return null;
}
}
http://localhost:8080/springmvc/old-controller을 통해 접속해서 콘솔에 출력이 되면 성공이다.
이 컨트롤러는 어떻게 호출이 되는걸까
스프링 MVC 구조
컨트롤러를 호출하려면 2가지가 필요하다.
- HandlerMapping
- 핸들러 매핑에서 이 컨트롤러를 찾을 수 있어야 한다.
- 스프링 빈의 이름으로 핸둘러를 찾을 수 있는 핸들러 매핑이 필요하다.
- 핸들러 매핑에서 이 컨트롤러를 찾을 수 있어야 한다.
- HandlerAdapter
- 핸들러 매핑을 통해서 찾은 핸들러를 실행할 수 있는 핸들러 어댑터가 필요하다.
- Controller 인터페이스를 실행할 수 있는 핸들러 어댑터를 찾고 실행해야 한다.
- 핸들러 매핑을 통해서 찾은 핸들러를 실행할 수 있는 핸들러 어댑터가 필요하다.
스프링은 이미 필요한 핸들러 매핑과 핸들러 어댑터를 대부분 구현됐기 때문에 개발자가 직접 핸들러 매핑과 핸들러 어댑터를 만드는 일은 거의 없다.
스프링 부트가 자동 등록하는 핸들러 매핑과 핸들러 어댑터
- HandlerMapping
- 0 순위 : RequestMappingHandlerMapping - 애노테이션 기반의 컨트롤러인 @RequestMapping에서 사용
- 1 순위 : BeanNameUrlHandlerMapping - 스프링 빈의 이름으로 핸들러를 찾는다.
- HandlerAdapter
- 0 순위 : RequestMappingHandlerAdapter - 애노테이션 기반의 컨트롤러인 @RequestMapping에서 사용
- 1 순위 : HttpRequestHandlerAdapter - HttpRequestHandler 처리
- 2 순위 : SimpleControllerHandlerAdapter - Controller 인터페이스(애노테이션X, 과거에 사용) 처리
1. 핸들러 매핑으로 핸들러 조회
- HandlerMapping을 순서대로 실행해서 핸들러를 찾는다.
- 이 경우 빈 이름으로 찾아야하기 때문에 BeanNameUrlHandlerMapping가 실행에 성공하고 핸들러인 OldController를 반환한다.
2. 핸들러 어댑터 조회
- HandlerAdapter의 supports()를 순서대로 호출한다.
- SimpleControllerHandlerAdapter가 Controller 인터페이스를 지원하므로 대상이 된다.
3. 핸들러 어댑터 실행
- 디스패처 서블릿이 조회한 SimpleControllerHandlerAdapter를 실행하면서 핸들러 정보도 함께 넘겨준다.
- SimpleControllerHandlerAdapter는 핸들러인 OldController를 내부에서 실행하고 결과를 반환한다.
정리
OldController를 실행하며 사용된 객체는 HandlerMapping = BeanNameUrlHandlerMapping
과 HandlerAdapter = SimpleControllerHandlerAdapter
다.
HttpRequestHandler
이해를 위해 Controller 인터페이스가 아닌 다른 핸들러를 사용해보자.
HttpRequestHandler는 서블릿과 가장 유사한형태의 핸들러다.
public interface HttpRequestHandler {
void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}
MyHttpRequestHandler
@Component("/springmvc/request-handler")
public class MyHttpRequestHandler implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("MyHttpRequestHandler.handleRequest");
}
}
http://localhost:8080/springmvc/request-handler을 통해 접속해서 콘솔에 출력이 되면 성공이다.
1. 핸들러 매핑으로 핸들러 조회
- HandlerMapping을 순서대로 실행해서, 핸들러를 찾는다.
- 이 경우 빈 이름으로 핸들러를 찾아야 하기 때문에 BeanNameUrlHandlerMapping가 실행에 성공하고 핸들러인 MyHttpRequestHandler를 반환한다.
2. 핸들러 어댑터 조회
- HandlerAdapter의 supports()를 순서대로 호출한다.
- HttpRequestHandlerAdapter가 HttpRequestHandler 인터페이스를 지원하므로 대상이 된다.
3. 핸들러 어댑터 실행
- 디스패처 서블릿이 조회한 HttpRequestHandlerAdapter를 실행하면서 핸들러 정보도 함께 넘겨준다.
- HttpRequestHandlerAdapter는 핸들러인 MyHttpRequestHandler를 내부에서 실행하고 결과를 반환한다.
정리
MyHttpRequestHandler를 실행하며 사용된 객체는 HandlerMapping = BeanNameUrlHandlerMapping
과 HandlerAdapter = HttpRequestHandlerAdapter
다.
@RequestMapping
가장 우선순위가 높은 핸들러 매핑과 핸들러 어댑터는 RequestMappingHandlerMapping
, RequestMappingHandlerAdapter
다.
지금 스프링에서 주로 사용하는 어노테이션 기반의 컨트롤러를 지원하는 매핑과 어댑터로 거의 이 방식의 컨트롤러를 사용한다.
출처 : 인프런 김영한 지식 공유자님 강의 - 스프링 MVC 1편 백엔드 웹 개발 핵심 기술
'BE > Spring' 카테고리의 다른 글
스프링 MVC 1 - 스프링 MVC 시작하기 (0) | 2022.08.12 |
---|---|
스프링 MVC 1 - 뷰 리졸버 (0) | 2022.08.12 |
스프링 MVC 1 - 스프링 MVC 구조 (0) | 2022.08.12 |
Spring - 테스트 코드 작성시 NPE (0) | 2022.07.22 |
Spring - SpringSecurity 사용해서 패스워드 암호화 하기 (0) | 2022.07.19 |