김영한님의 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 강의를 들으면서 공부한 내용을 기록한 글이다.
Dispatcher Servlet도 부모 클래스에서 HttpServle을 상속받아서 사용하고, 서블릿으로 동작한다.
스프링 부트는 Dispatcher Servlet을 서블릿으로 자동으로 등록하면서 모든 경로(urlPatterns="/")에 대해서 매핑한다.
서블릿이 호출되면 부모 인터페이스에 오버라이드된 Service()가 호출되며 이를 시작으로 여러 메서드가 호출되며 DispatcherServlet.doDispatch()가 호출된다.
동작순서
1. 핸들러 조회
2. 핸들러 어댑터 조회
3. 핸들러 어댑터 실행
4. 핸들러 실행
5. ModelAndView 반환
6. viewResolver 호출
7. View 반환
8. 뷰 렌더링
과거 버전의 스프링 컨트롤러: Controller 인터페이스
@Controller와는 다른 것이다.------------------OldController---------------------------
@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;
}
}
@Component를 통해 이 컨트롤러는 빈의 이름으로 URL을 매핑할 것이다.
0 = RequestMappingHandlerMapping : 애노테이션 기반의 컨트롤러인 @RequestMapping에서 사용
1 = BeanNameUrlHandlerMapping : 스프링 빈의 이름으로 핸들러를 찾는다.
0 = RequestMappingHandlerAdapter : 애노테이션 기반의 컨트롤러인 @RequestMapping에서 사용
1 = HttpRequestHandlerAdapter : HttpRequestHandler 처리
2 = SimpleControllerHandlerAdapter : Controller 인터페이스(애노테이션X, 과거에 사용) 처리
핸들러 매핑 시 우선순위에 따라 핸들러를 찾는다. 1순위는 일반적으로 사용되는 @RequestMapping에서 사용되는 핸들러이고 예제의 OldController는 2순위의 SimpleControllerHandlerAdapter가 실행된다.
핸들러 어댑터 역시 우선순위에 따라 조회되며 1순위 역시 위의 설명과 같다. 예제는 3순위의 핸들러 어댑터가 실행된다.
@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 new ModelAndView("new-form");
}
}
예제를 View 조회가 가능하도록 변경한 것이다.
웹 브라우저에서 정상적으로 실행이 되려면 application.properties에 설정을 추가하여야 한다.
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
스프링부트는 InternalResourceViewResolver라는 뷰 리졸버를 자동으로 등록하는데, 이때 위에서 설정한 정보를 사용해서 등록한다.
1 = BeanNameViewResolver : 빈 이름으로 뷰를 찾아서 반환한다. (예: 엑셀 파일 생성 기능에 사용)
2 = InternalResourceViewResolver : JSP를 처리할 수 있는 뷰를 반환한다.
핸들러 어댑터를 통해 new-form 이라는 뷰 이름으로 ViewResolver를 순서대로 호출한다.
1순위인 BeanNameViewResolver는 new-form이라는 이름의 스프링 빈으로 등록된 뷰를 찾아야 하는데 없기 때문에 InternalResourceViewResolver기 호출된다.
이 뷰 리졸버는 InternalResourceoView를 반환하며 forward()를 처리한다.
본 포스팅에서 알아본 과거 Controller를 통한 동작 방식은 현 실무에서 전혀 쓰이는 방식이 아니다. 하지만 이를 통해 SpringMVC가 어떻게 동작하는지 알 수 있고 이를 통해 추후 SpringMVC에서 에러가 발생했을 때 원인을 파악하고 해결하는데 도움을 줄 정보들이기에 참고해 두는 것을 추천한다.