김영한님의 스프링 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에서 에러가 발생했을 때 원인을 파악하고 해결하는데 도움을 줄 정보들이기에 참고해 두는 것을 추천한다.