인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

australialove19님의 프로필 이미지
australialove19

작성한 질문수

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

스프링 MVC - 시작하기

HandlerAapter가 어떻게 각 메서드를 실행할 수 있는가?

작성

·

26

0

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.

1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)

[질문 내용]
안녕하세요. 저와 비슷한 질문이 있어서

https://www.inflearn.com/questions/1292736

이 글을 보았는데요, 이 글을 읽고 핸들러 매핑하는 과정까지는 잘 이해했다고 생각하고 있습니다.

 

package hello.servlet.web.springmvc.v3;


import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

@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";
    }
}

 

<이해된 부분>

SpringMemberControllerV3 클래스의 메서드들은 RequestMappingHandlerMapping에 의해 매핑되고, 이들을 실행하기 위해 RequestMappingHandlerAdapter가 사용됩니다.

따라서, 핸들러(메서드, 컨트롤러)는 SpringMemberControllerV3 클래스이고, 이 클래스의 메서드가 핸들러 메서드입니다. 핸들러 어댑터는 RequestMappingHandlerAdapter가 됩니다.

=============================

<이해되지 않은 부분>

디스패처 서블릿은 요청이 들어올 때 이 매핑된 정보들을 활용하여 핸들러와 핸들러 어댑터를 찾고, 이를 통해 요청을 처리합니다.

============================

/springmvc/v3/members 요청이 들어왔을 때 RequestMappingHandlerMapping에 의해 매핑이 되고, 이들을 실행하기 위해서 RequestMappingHandlerAdapter가 실행이 되어야 하는데 프레임워크의 생명주기처럼 자동으로 실행이 되는건가요..? (눈에 보이지 않아서 잘 모르겠습니다 ㅠㅠ 이전 강의처럼 인터페이스를 구현한것도 아니기 때문입니다..!)

예전 예시에서는 Controller 인터페이스를 구현하면 구현한 메서드를 호출하는 과정이 이해가 되었는데,

지금은 보다시피 개발자가 원하는 대로 메서드명을 마음대로 지정할 수 있기 때문에, 이게 어떻게 스프링에서 가능한것인지 잘 이해하지 못하겠습니다..!

예전 예시에서는 오버라이딩을 하기때문에, 당연히 오버라이딩이 된 것이 호출되겠구나! 했는데,

save나 members와 같이 개발자가 마음대로 정한 메서드이름을 어떻게 알고 딱딱 실행을 하는지.. 잘 모르겠습니다 ㅠㅠ

================

정리

  1. 핸들러 매핑을 하고, 어댑터 목록에서 RequestMappingHandlerAdapter를 호출하는 것까지는 이해완료.

  2. 이 어뎁터가 어떻게 각 메서드를 호출하는지 이해하지 못하는 상황(메서드이름은 마음대로 바뀔 수 있기 때문에)

  3. 스프링 MVC 전체 구조 그림으로 봤을 때, 사용자가 요청을 하게된다면 @RequestMapping(@Controoler)에 정한 URL에따라 핸들러 매핑, 핸들러 어댑터 목록을 가져오고 해당 메서드를 실행한다고 한다면, RequestMappingHandlerAdapter가 자동으로 어댑터로 지정이 되고 해당 메서드가 실행이 되면 이 메서드가 핸들러(컨드롤러)가 되는것이 맞는지 궁금합니다 !

답변 2

0

안녕하세요. australialove19님, 공식 서포터즈 y2gcoder입니다.

매우 좋은 질문을 해주셨다고 생각합니다! 저는 australialove19님께서 현재 리플렉션에 대해서만 학습하시면 질문해주셨던 부분을 이해하실 수 있다고 생각합니다!

개인적으로는 영한님의 김영한의 실전 자바 - 고급 2편, I/O, 네트워크, 리플렉션 강의를 학습하시는 것을 추천합니다. 해당 강의의 리플렉션 파트까지 학습하시고 나면 스프링에서 애노테이션 기반의 핸들러 매핑 또한 대략 이런 식으로 리플렉션을 이용해 핸들러 메서드를 실행하겠구나라고 생각하실 수 있게 되실 거라 생각합니다!

감사합니다.

0

안녕하세요, 인프런 AI 인턴입니다. australialove19 님의 질문에 답변드립니다.

스프링 MVC에서 요청을 처리하는 방법은 비교적 복잡하지만, 스프링이 제공하는 유연성 덕분에 실제 코딩은 더 간결하게 처리할 수 있습니다. SpringMemberControllerV3 클래스와 관련된 핸들러 처리 과정을 아래와 같이 설명드리겠습니다.

이해된 부분 확인:

  • RequestMappingHandlerMappingSpringMemberControllerV3의 메서드들을 적절한 URL 패턴에 매핑합니다.
  • 핸들러 메서드는 SpringMemberControllerV3 클래스의 각각의 메서드(newForm, save, members)입니다.
  • RequestMappingHandlerAdapter는 핸들러 메서드를 실행할 수 있는 핸들러 어댑터로 사용됩니다.

핸들러 어댑터의 역할:

  1. 메서드와 URL 매핑:

    • @RequestMapping과 같은 어노테이션은 메서드와 URL을 매핑하는 역할을 합니다. 이는 HandlerMapping에 의해 관리되며, 모든 요청에 대해 어떤 컨트롤러 메서드가 호출될지 결정합니다.
  2. 메서드 실행 과정:

    • 스프링은 리플렉션(reflection)을 사용하여, 컨트롤러 클래스에서 URL과 매핑된 메서드를 실행합니다.
    • RequestMappingHandlerAdapter는 매핑된 메서드의 정보를 바탕으로 적절한 인자를 주입한 후, 해당 메서드를 호출합니다.
    • 스프링은 어노테이션 기반 프로그래밍을 통해, 개발자가 메서드 이름을 자유롭게 설정할 수 있도록 하며, URL 패턴 등을 통해 적절한 메서드를 자동으로 찾아 실행합니다.

핸들러 매핑 및 호출 자동화:

  • 생명주기 관리: 스프링의 어플리케이션 컨텍스트(Application Context)가 시작될 때, 설정 파일 혹은 클래스에서 정의된 컨트롤러 빈을 스캔하고 RequestMappingHandlerMapping과 같은 매핑 정보를 준비합니다.
  • 자동 실행: 요청이 들어오면, 디스패처 서블릿(DispatcherServlet)이 사전 정의된 매핑 정보를 사용하여 매핑된 핸들러 어댑터를 통해 적절한 메서드를 호출하게 됩니다. 이 모든 과정은 스프링의 내부 메커니즘으로 자동화되었습니다.

기존에 Controller 인터페이스를 사용한 방식은 많은 코드가 필요했고, 메서드 명도 고정되었습니다. 그러나 스프링 MVC는 어노테이션 기반으로 동작하면서 이런 복잡성을 많이 줄여주었습니다.

위 내용을 바탕으로 질문해주셨던 부분에 대한 이해가 조금 더 명확해졌기를 바랍니다. 다음과 같은 유사한 질문들이 있어 참고하시면 좋을 것 같습니다:

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

australialove19님의 프로필 이미지
australialove19

작성한 질문수

질문하기