도입 전
도입 후
controller
코드 중복controller
가 비즈니스 로직에만 집중 할 수 있게 되었지만,controller
를 작성하다보면 controller
마다 중복되는 코드가 존재함ex) view 주소, 해당 view로 forward 하는 부분 등
controller
공통 처리하기의 어려움클라이언트 요청 ( 모든 요청 )
-> FrontController
에서 각 요청에 맞는 controller
호출
FrontController
에서 공통으로 처리해야하는 부분 처리 가능controller
중복 코드 제거FrontController
외에 다른 controller
는 서블릿을 사용하지 않아도 됨FrontController
에서 한 가지 패턴의 controller
를 정의 해놓으면, 그 패턴의 controller
만을 사용할 수 있는데, 이것을 다양한 패턴으로 사용할 수 있도록 하기 위해 사용이 되었다.
여기서 핸들러란
controller
로 두고 이해하면 이해하기 좀 더 쉽다.
어댑터가 지원하기만하면 어떤 것이라도 URL에 매핑해서 사용할 수 있기에 이름을controller
->handler
로 변경
핸들러 어댑터 : 다양한 controller
와 FrontController
중간에 어댑터 역할
핸들러 어댑터 역할
스프링 MVC도 FrontController
패턴으로 구현, FrontController
=> DispatcherServlet
DispatcherServlet
도 HttpServlet
을 상속 받아서 사용하고 서블릿으로 동작DispatcherServlet
가 바로 상속하는 것은 아니고DispatcherServlet
-> FrameworkServlet
-> HttpServletBean
-> HttpServlet
DispatcherServlet
은 모든 경로(urlPatterns="/")
에 대해 매핑controller
에서 매핑한 것이 우선 순위가 더 높다.서블릿이 호출되면 HttpServlet
이 제공하는 serivce()
가 호출 ( 이때 serivce()
는
DispatcherServlet
의 부모인 FrameworkServlet
에서 오버라이드 )
-> DispacherServlet.doDispatch()
호출
DispacherServlet.doDispatch()
: 요청에 맞는 처리를 하는 핵심 로직
여기서 핸들러란
controller
로 두고 이해하면 이해하기 좀 더 쉽다.
먼저 요청이 들어왔을 때, 핸들러 매핑을 통해 요청 URL에 매핑된 핸들러(=컨트롤러)를 조회
핸들러 매핑 :
/test
라는 요청이 왔을 떄는 어떤controller
로 처리를 할건지 매핑되어있는 것
{(/save
,SaveController
), (/select
,SelectController
) ,,,} 대략 이런식
1. 핸들러 조회
를 통해 조회된 핸들러(=컨트롤러)
를 실행할 수 있는 핸들러 어댑터
를 조회
핸들러 어댑터
를 실행
핸들러 어댑터
가 실제 핸들러(=컨트롤러)
를 실행
핸들러 어댑터
는 핸들러(=컨트롤러)
가 반환하는 정보를 ModelAndView
로 변환해서 반환
뷰 리졸버
를 찾고 실행
뷰 리졸버
는 뷰의 논리 이름
을 물리 이름
으로 바꾸고, 렌더링 역할을 담당하는 뷰 객체를 반환
논리 뷰 이름:
test
물리 뷰 경로:/WEB-INF/jsp/test.jsp
뷰 리졸버 :논리 이름
을물리 이름
으로 변경하고, 변경된물리 이름
으로뷰 객체
를 찾아 반환 함
논리 이름
과물리 이름
을 구분하는 이유 : 앞에/WEB-INF/jsp/
부분이 공통이라 중복이 되기도하고, 유지보수를 진행하면서 jsp파일이 있는 경로가 변경되었을 때 한 곳만 수정하면 되기 때문에 구분하여 사용
뷰 리졸버 - InternalResourceViewResolver
spring boot는InternalResourceViewResolver
라는 뷰 리졸버를 자동으로 등록하는데, 이떄application.properties
에서 등록한spring.mvc.view.prefix
,spring.mvc.view.suffix
설정 정보를 사용해서 등록!
뷰
를 통해서 뷰를 렌더링