해결된 질문
작성
·
137
·
수정됨
0
@Controller
@RequestMapping("/springmvc/v3/members")
public class SpringMemberControllerV3 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@GetMapping("/new-form")
public String newForm() {
return "new-form";
}
@PostMapping("/save")
public String save(@RequestParam("username") String username,
@RequestParam("age") int age,
Model model) {
Member member = new Member(username, age);
memberRepository.save(member);
model.addAttribute("member", member);
return "save-result";
}
@GetMapping
public String members(Model model) {
List<Member> members = memberRepository.findAll();
model.addAttribute("members", members);
return "members";
}
}
코드를 실행하면 스프링 빈에 Controller가 붙은 SpringMemberControllerV3가 등록되고, 자동으로 맵핑도 됩니다.
질문:
http 요청이 오면, mapping된 핸들러를 찾습니다. 여기서 핸들러는 SpringMemberControllerV3인 건가요?
핸들러가 핸들러 어댑터를 찾아야하는데 핸들러 어댑터 맵핑 할 때는 뭐가 등록이 되는 건가요?
제가 이해한 건 SpringMemberControllerV3 클래스가 핸들러 어댑터로 등록이 되고, SpringMemberControllerV3 클래스 안에 있는 메서드가 핸들러로 등록이 되는 거 맞나요?
어떤게 핸들러 어댑터고 어떤 게 핸들러(컨트롤러) 인지 잘 모르겠습니다.
여기서는 핸들러(컨트롤러)만 만들어놓은 거 같은데 여기서 핸들러 어댑터는 뭐로 맵핑이 되는지를 몰라서 핸들러 어댑터를 찾을 때 어떤 것과 비교를 하는 건가요?
답변 2
2
안녕하세요. 권정익님
스프링 MVC에서 HTTP 요청이 오면 요청을 처리하기 위해 핸들러와 핸들러 어댑터가 사용됩니다. 이를 이해하기 위해 다음과 같은 개념들을 정리해 보겠습니다.
핸들러, 핸들러 메서드
핸들러는 실제 요청을 처리하는 코드입니다.
우리가 앞서 공부하면서 직접 만들어본 핸들러는 단순히 컨트롤러 객체 단위라고 생각하시면 됩니다.
그런데 스프링MVC가 메서드 단위로 호출할 수 있는 기능을 부여하면서 핸들러가 객체 -> 메서드 단위로 더 세분화 됩니다.
핸들러 -> 단순히 컨트롤러
핸들러 메서드 -> 메서드 단위로 구분
그래서 이제는 핸들러의 단위를 단순히 컨트롤러가 아니라, 컨트롤러와 호출 대상인 메서드까지 포함된 핸들러 메서드라고 이해하시면 됩니다.
핸들러 어댑터 (Handler Adapter)
- 핸들러 어댑터는 핸들러를 실행하는 방법을 아는 객체입니다. 스프링 MVC는 다양한 유형의 핸들러를 지원하기 위해 여러 가지 핸들러 어댑터를 제공하며, 이들은 특정 타입의 핸들러를 호출하는 역할을 합니다.
- RequestMappingHandlerAdapter
는 그 중 하나로, 주로 @RequestMapping
, @GetMapping
, @PostMapping
등의 어노테이션이 붙은 메서드를 처리하는 어댑터입니다. 이 어댑터가 앞서 설명한 핸들러 메서드를 처리할 수 있습니다.
질문: HTTP 요청이 오면, 매핑된 핸들러를 찾습니다. 여기서 핸들러는 SpringMemberControllerV3
인가요?
네 맞습니다. 다만 조금 더 세분화 하면 이제는 메서드 단위로도 처리가 되어야 하기 때문에 핸들러 대신에 핸들러 메서드라는 단어를 사용하겠습니다. 해당 컨트롤러 뿐만 아니라 해당 컨트롤러의 메서드를 포함합니다.
질문: 핸들러가 핸들러 어댑터를 찾아야 하는데 핸들러 어댑터 매핑할 때는 뭐가 등록이 되는 건가요?
스프링 MVC는 여러 핸들러 어댑터를 기본적으로 등록합니다. @RequestMapping
어노테이션이 붙은 메서드를 처리하는 RequestMappingHandlerAdapter
도 그 중 하나입니다. 핸들러 어댑터는 특정 핸들러의 타입을 지원하는지 확인하여 적절한 어댑터를 선택합니다.
질문: 제가 이해한 건 SpringMemberControllerV3
클래스가 핸들러 어댑터로 등록이 되고, SpringMemberControllerV3
클래스 안에 있는 메서드가 핸들러로 등록이 되는 거 맞나요?
앞서 설명드린 것 처럼 이제는 메서드 단위로 핸들러가 등록됩니다. 그래서 이름도 핸들러 메서드라고 부릅니다.
질문: 여기서는 핸들러(컨트롤러)만 만들어놓은 것 같은데 여기서 핸들러 어댑터는 뭐로 매핑이 되는지를 몰라서 핸들러 어댑터를 찾을 때 어떤 것과 비교를 하는 건가요?
스프링 MVC가 요청을 처리하는 순서는 다음과 같습니다:
1. 디스패처 서블릿이 HTTP 요청을 받습니다.
2. 디스패처 서블릿은 핸들러 매핑을 사용하여 요청 URL에 매핑된 핸들러(컨트롤러 메서드)를 찾습니다.
3. 핸들러를 찾은 후, 디스패처 서블릿은 그 핸들러를 실행할 수 있는 핸들러 어댑터를 찾습니다. 이 과정에서 핸들러 어댑터는 자신이 지원하는 핸들러 타입을 기준으로 적합한지 판단합니다.
4. 핸들러 어댑터가 핸들러를 호출하여 요청을 처리합니다.
SpringMemberControllerV3
클래스의 메서드들은 RequestMappingHandlerMapping
에 의해 매핑되고, 이들을 실행하기 위해 RequestMappingHandlerAdapter
가 사용됩니다.
따라서, 핸들러(메서드, 컨트롤러)는 SpringMemberControllerV3
클래스이고, 이 클래스의 메서드가 핸들러 메서드입니다. 핸들러 어댑터는 RequestMappingHandlerAdapter
가 됩니다. 디스패처 서블릿은 요청이 들어올 때 이 매핑된 정보들을 활용하여 핸들러와 핸들러 어댑터를 찾고, 이를 통해 요청을 처리합니다.
감사합니다.
1
안녕하세요, 인프런 AI 인턴입니다. 권정익 님의 질문에 답변드립니다.
스프링 MVC의 동작 원리와 관련해 핸들러와 핸들러 어댑터의 역할에 대해 궁금증을 가지신 것 같습니다. 코드 예제에 기반한 질문에 대응하기 위해, 관련 내용을 담고 있는 인프런 게시글 몇 가지를 추천드립니다.
@Controller 사용시 HTTP 요청 과정 질문 / 핸들러 어댑터 과정에서는 스프링 MVC에서 @Controller
어노테이션이 붙은 클래스가 어떻게 HTTP 요청을 처리하는지, 그리고 핸들러 어댑터의 역할이 무엇인지에 대해 설명되어 있습니다. 이 내용은 질문자님의 질문 4와 5에 대한 이해를 돕는 데에 유용할 것입니다.
SpringMemberFormControllerV1 부분 질문입니다. 이 포스트에서는 ModelAndView
객체의 역할과, 핸들러 어댑터가 어떻게 작동하는지에 대한 설명이 포함되어 있습니다, 이것은 질문 3에 대한 부분적인 설명을 제공할 수 있습니다.
위의 게시글에서는 스프링 MVC의 요청 처리 과정에서 핸들러(컨트롤러)와 핸들러 어댑터의 역할을 자세히 설명하고 있습니다. 먼저, HTTP 요청이 들어오면 DispatcherServlet은 핸들러 매핑 정보를 바탕으로 적절한 핸들러(컨트롤러의 메서드)를 찾아 핸들러를 처리할 수 있는 핸들러 어댑터를 찾습니다. 각 요청에 맞는 컨트롤러의 메서드가 핸들러로 작동하며, @Controller
어노테이션이 붙은 클래스 자체는 스프링에서 관리하는 빈으로 등록됩니다.
따라서, SpringMemberControllerV3 클래스는 스프링 애플리케이션 컨텍스트에서 관리하는 빈입니다. 핸들링해야 할 요청이 들어오면 해당 요청을 처리할 메서드(핸들러)가 호출되며, 핸들러 어댑터는 이 핸들러를 실행하기 위한 매커니즘을 제공합니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
이번에는 핸들러 어탭터를 만들지 않았고, 스프링에서 자동으로 핸들러 어댑터를 생성한다면, SpringMemberControllerV3에 맞는 핸들러 어댑터가 생성되어있을 거고, 그 핸들러 어댑터가 SpringMemberControllerV3(핸들러)를 실행시켜줄텐데 SpringMemberControllerV3에는 핸들러 안에 메서드가 3개나 있습니다. 그리고 3개의 메서드는 각자 다른 이름을 가지고있습니다.
v4에서 만들었던 핸들러 어댑터는 핸들러의 실행 메서드가 process로 통일되어있었지만, 지금은 아닙니다. 그러면 핸들러 어댑터는 어떻게 핸들러 안의 메서드를 구분하는 건가요??
하나하나 질문에 답변해주셔서 감사드립니다ㅠㅠ
답변 덕분에 머릿속에서 어느 정도 정리 된 거 같습니다!! 감사합니다!!