작성
·
516
0
안녕하세요 선생님!
스프링 입문 강의부터 잘 따라가고 있다가 컨트롤러 인터페이스 부분에서 막혀서 질문 드립니다.
전 강의 '유연한 컨트롤러' 강의를 보면 FrontControllerServletV5에서는
핸들러 매핑정보를 Map<String, Object> handlerMappingMap에 담았고,
getHandler메소드를 통해 handlerMappingMap.get(requestURI);로 반환하여 핸들러를 찾았습니다.
제가 이해한 컨트롤러 호출과정은,
핸들러 조회 - getHandler(request); =>handlerMappingMap.get(requestURI);으로.
핸들러 어댑터 조회 - getHandlerAdapter(handler);
핸들러 어댑터 실행 - adapter.handle(request, response, handler);
이라고 알고있었습니다.
그런데 이번에 핸들러 매핑과 핸들러 어댑터 강의에서 Controller인터페이스를 사용한 OldController를 보니, 이렇게 설명이 나와있습니다.
그렇다면 ,
위와 같은 순서가 아니라 핸들러를 찾는 방법 선정이 먼저인
적절한 핸들러 매핑방법 찾기 (RequestMappingHandlerMapping 인지, BeanNameUrlHandlerMapping 인지)
찾은 핸들러 매핑으로 핸들러 조회
핸들러 어댑터 조회
핸들러 어댑터 실행
이렇게 이해를 했습니다.
질문입니다.
1 . 그러면 V5와의 차이점이 ,
V5는 핸들러 매핑방법이 handlerMappingMap.get(requestURI); 이거 하나였는데, Controller인터페이스를 적용한 부분은 핸들러 매핑방법이 RequestMappingHandlerMapping, BeanNameUrlHandlerMapping 이렇게 두개(실제로는 더 많다고 하셨으니 여러개)가 된 것인가요???
2. 매핑 방법이 두개가 된 이유는 지금까지 스프링을 사용하지 않은 서블릿으로만 사용했기 때문에 컨트롤러를 Map으로만 관리하다가, 이제는 컨트롤러를 @Component를 이용해 스프링 빈으로 등록을 해서, Map이 아닌 스프링빈으로 관리를 해서 그런건가요??
3. 그렇다면 이 때, 컨트롤러 저장소(?) 모양의 변화는 아래와 같나요?
이 모양에서
이모양으로 바뀐건가요?
그리고 여기서 스프링 빈 저장소의 빈 객체는 OldController인가요? 아니면 null인가요? .. 반환값이 null이어서..
4. 빈 이름으로 등록하지 않고 @RequestMapping으로 등록한다면 스프링 빈 저장소의 모양은 위의 빈 저장소와 동일한가요?
5. 교재에서 DispacherServlet.doDispatch()의 핸들러 조회 부분인 getHandler메소드가 적혀있지 않은데 일부러 안적으신건가요?
아래의 V5의 getHandler메소드처럼 핸들러 조회할 때 Map을 뒤져서 가져오는걸 바로 파악해서 이해하기 좋았는데
doDispatch()에는 위 메소드가 없더라구요ㅠ.. 어떻게 뒤져서 가져오는 지 흐름이 궁금합니다.
아니면 스프링이 제공해줘서 메소드가 없는건지?
있다면 메소드 코드를 알려주실 수 있나요? (제가 못찾는건지 인텔리제이 검색이 안나오네요..ㅠ)
더 궁금한 게 많지만 여기 까지 질문 하겠습니다. 혹시 위에서 제가 다르게 이해하고 있는 부분이 있거나, 앞서 들은 강의에서 부족한 개념이 있어 보이시면 알려주시면 감사하겠습니다.
그리고 강의 너무 재밌고 좋아요!
감사합니다!!
답변 1
1
안녕하세요, 현주 님. 공식 서포터즈 y2gcoder 입니다.
저희가 만든 프론트 컨트롤러에서는 핸들러 매핑을 저장하는 방법이 하나였다면, 말씀하신대로 스프링 MVC에서는 @RequestMapping, 스프링 빈의 이름 등으로 핸들러 매핑 정보를 저장하는 방법이 늘어났다고 보시면 될 것 같습니다.
저희가 만든 프론트 컨트롤러에서는 스프링 MVC의 다양한 핸들러 매핑 방법과 그에 따른 핸들러 어댑터 종류들 중 일부를 구현하면서 DispatcherServlet의 핵심 구조를 이해하는데 초점을 맞췄다고 이해해주시면 감사하겠습니다.
핸들러 매핑 저장소는 DispatchServlet의 List<HandlerMappings> handlerMappings; 이며, 각 핸들러 매핑 저장 방법마다 인터페이스인 HandlerMapping을 구현한 객체를 저장하고 있다고 보시면 됩니다. HandlerMapping 구현체에 따라 구현한 getHandler(HttpServletRequest request) throws Exception 를 통해 저마다 각 핸들러 매핑 방법에 맞게 해당 핸들러를 찾아올 수 있습니다.
스프링 빈 저장소에는 컨트롤러가 저장되어있고, 핸들러 매핑 저장소는 위에 설명한 3번과 같습니다. 빈이 구동할 때 해당 핸들러 매핑 정보들도 같이 저장하게 되며 일부긴 하나 @RequestMapping의 방식에서는 링크와 같이 작동하는 것으로 보입니다.
DispatcherServlet의 doDispatch() 메서드에서
다음 1036번 라인을 보시면 getHandler()를 호출하고 있으며, getHandler()는
다음과 같습니다. 여기서 앞서 말씀드렸던대로 핸들러 매핑 정보가 담긴 handlerMappings를 순회하면서 request를 이용해 맞는 핸들러를 찾아오고 있습니다.
감사합니다.