본문 바로가기
Spring Framework/스프링

스프링 MVC 패턴 의미와 구조 [정리]

by 스코리아 2024. 8. 9.
반응형

안녕하세요, 스코리아입니다.

오늘은 스프링 MVC 패턴의 의미와 구조에 대해서 살펴보겠습니다.

Spring MVC Pattern

 

MVC 패턴 의미

  • MVC는 Model View Controller의 줄임말
  • 애플리케이션 개발 영역을 Model, View, Controller로 구분해서 역할에 맞게 개발하는 방식
  • MVC 패턴 이전에는 뷰 안에 비즈니스 로직이 있는 등, 한 곳에 모든 것을 짬뽕한 느낌이었다면, MVC 패턴 도입 후에는 UI(뷰) 영역과 비즈니스 로직이 명확하게 구분되어 개발과 유지보수가 편리해짐

  • Model: 뷰에 출력할 데이터를 담아줌
  • View:  뷰는 비즈니스 로직이나 데이터 접근을 몰라도 되며, 모델에 담겨 있는 데이터를 이용하여 화면 렌더링에 집중
  • Controller: HTTP 요청을 받아서 파라미터 검증 -> 비즈니스 로직 실행 -> 뷰에 전달할 결과 데이터를 조회 후 모델에 담음

 

 

MVC 프레임워크의 발전

MVC 패턴 초창기에는 HttpServlet을 상속받은 클래스 파일을 만들고 안에 Model에 데이터를 보관하는 부분과 서비스(비즈니스로직)를 호출하는 부분을 만들었습니다. 또한 뷰는 화면을 그리는 역할만 하도록 하여, 뷰와 비즈니스 계층을 명확하게 구분하였습니다. 하지만 클래스마다 항상 뷰로 이동하는 코드(포워드)가 중복 호출되었고, viewPath 이름이 중복되었습니다.

 

또한 가장 핵심은 중복되는 부분을 공통 처리하기가 어려웠습니다. 복잡한 부분을 공통처리 하기 위해 메소드를 뽑아도 해당 메소드 호출이 계속 필요했고, 호출하는 것만으로도 코드 중복에 해당하기 때문입니다.

따라서 컨트롤러 호출 전에 먼저 공통 기능을 처리해야 했습니다. 

 

 

그래서 등장한 게 Front Controller입니다. 특징은 다음과 같습니다.

  • 서블릿 하나로 클라이언트 요청을 받음
  • 프런트 컨트롤러가 알아서 요청에 맞는 컨트롤러 찾아서 호출
  • 공통 처리 가능
  • 나머지 컨트롤러는 서블릿 사용 X
  • 스프링 MVC의 DispatcherServlet이 FrontController 패턴

 

FrontController를 직접 구현하는 부분은 내용이 길어질 것 같아서 생략하겠습니다. 하지만 직접 구현한 FrontController와 실제 스프링 MVC가 작동하는 방식은 매우 유사하기 때문에 이해하는데 많은 도움이 됩니다.

 

 

Spring MVC 구조

FrontController가 실제 스프링에서는 DispatcherServlet로 작동합니다.

DispatcherServlet는 똑같이 HttpServlet을 상속받아서 사용하며 서블릿으로 동작합니다.

 

스프링 부트는 DispatcherServlet을 서블릿으로 자동 등록하고, 모든 경로(urlPatterns=”/”)를 매핑하게 됩니다. 여기서 더 자세한 경로가 우선순위가 높기 때문에 기존에 등록한 서블릿도 함께 잘 동작합니다.

Spring MVC 구조

동작 순서

  1. 핸들러 조회: 핸들러 매핑을 통해 요청 URL에 매핑된 핸들러(컨트롤러)를 조회
    • HandlerMapping 순서
      • 0 = RequestMappingHandlerMapping : 애노테이션기반의 컨트롤러인 @RequestMapping에서 사용
      • 1 = BeanNameUrlHandlerMapping : 빈 이름으로 검색
  2. 핸들러 어댑터 조회: 핸들러를 실행할 수 있는 핸들러 어댑터를 조회
    • HandlerAdpater 순서
      • 0 = RequestMappingHandlerAdapter: 애노테이션기반의 컨트롤러인 @RequestMapping에서 사용
      • 1 = HttpRequestHandlerAdapter: HttpRequestHandler 처리
      • 2 = SimpleControllerHandlerAdapter : Controller 인터페이스 (애노테이션 X, 과거에 사용)
  3. 핸들러 어댑터 실행: 핸들러 어댑터를 실행
  4. 핸들러 실행: 핸들러 어댑터가 실제 핸들러(컨트롤러)를 실행
  5. ModelAndView 반환: 핸들러 어댑터는 핸들러가 반환하는 정보를 ModelAndView로 변환해서 반환
  6. viewResolver 호출: 뷰 리졸버를 찾고 실행 (JSP의 경우: InternalResourceViewResolver가 자동 등록)
    • ViewResolver 순서
      • 0 = BeanNameViewResolver : 빈 이름으로 뷰를 찾아서 반환 (예: 엑셀 파일 생성 기능에 사용)
      • 1 = InternalResourceViewResolver : JSP를 처리할 수 있는 뷰를 반환
  7. View 반환: viewResolver는 뷰의 논리이름을 물리이름으로 바꾸고, 렌더링 역할을 담당하는 뷰 객체를 반환 (JSP의 경우 InternalResourceView(JstlView)를 반환하는데, 내부에 forward() 로직이 있음)
  8. 뷰 렌더링: 뷰를 통해서 뷰를 렌더링

 

현대 어노테이션 기반의 스프링 MVC

  • @RequestMapping
    • 가장 높은 우선순위 지님: RequestMappingHandlerMapping / RequestMappingHandlerAdapter
    • 따로 @Component 어노테이션 안 붙여도 동작은 함.
  • @Controller
    • 스프링이 자동으로 스프링 빈 등록 (내부에 @Component 어노테이션이 있어서 컴포넌트 스캔됨)
    • 스프링 MVC에서 어노테이션 기반 컨트롤러로 인식
    • 스프링 3.0 이상부터는 해당 어노테이션이 무조건 있어야 스프링 컨트롤러로 인식
  • @RequestMapping(”/path”)
    • 요청 정보 매핑
    • 해당 URL이 호출되면, 메소드 호출

 

  • @RequestParam
    • 메소드에서 HTTP 요청 파라미터를 @RequestParam으로 받을 수 있음
    • GET, POST 모두 지원
    • @RequestParam("username") == request.getParameter("username")
  • @GetMapping, @PostMapping
    • @RequestMapping(value = "/new-form", method = RequestMethod.GET)
    • @GetMapping
    • @PostMapping
    • 모두 같음

 

아래는 간단한 코드 예시입니다.

Model을 파라미터로 받고, model 안에 addAttribute로 데이터를 담습니다. 그 후 함수의 반환값은 String으로 설정하고 뷰의 논리 이름을 반환하였습니다.

@Controller
@RequestMapping("/springmvc/v3/members")
public class SpringMemberControllerV3 {
    private MemberRepository memberRepository = MemberRepository.getInstance();

    @PostMapping("/save") // URL 경로: /springmvc/v3/members/save
    public String save(
            @RequestParam("username") String username, // Post Data
            @RequestParam("age") int age, // Post Data
            Model model // Model Parameter
    ) {
        Member member = new Member(username, age);
        memberRepository.save(member);

        model.addAttribute("member", member); // model에 데이터 넘겨주기
        return "save-result"; // 반환값 String (뷰의 논리이름 반환)
    }
}

 


지금까지 스프링 MVC 패턴 의미와 구조에 대해서 살펴보았습니다.

읽어주셔서, 감사합니다.

반응형