Spring MVC 구조와 동작

dropKick·2023년 4월 30일
0

스터디

목록 보기
6/20

목표

  • Spring의 간단한 변천사를 알아본다
  • Spring MVC 구조를 이해한다
  • Spring MVC의 동작을 이해한다

Spring의 발전과 MVC의 탄생

Spring Framework

  • 2023년 기준으로 말하는 Spring Framework(이하 스프링)은 스프링 5를 의미함
  • 스프링을 말할 때는 보통 Spring WEB MVC(이하 스프링 MVC)를 칭함
  • 스프링 4.0에서 Spring Boot(이하 스프링부트)가 등장하면서, 기존의 스프링은 Spring Legacy(스프링 레거시)로 불리게 됨

Spring Framework 구조

Spring Framework Runtime

Java Servlet과 Servlet Container

Java Servlet

  • Java Servlet(이하 서블릿)Common Gateway Interface(이하 CGI)를 자바 클래스로 '잘' 구현하기 위한 프로그램으로 javax.servlet 패키지로 구현되어 있음
  • 일반적으로 동적으로 페이지를 구현할 수 있는 프로그램이라고만 생각하지만, 서블릿 자체도 CGI 통신 규약을 통해 동작함
  • 서블릿에 대한 자세한 내용은 이전에 공부했던 서블릿과 JDBC 아키텍처를 참고

Servlet Container

  • 일반적으로 말하는 WEB Container/Servlet Container(이하 서블릿 컨테이너)Apache Tomcat Web Application Server(이하 톰캣)을 말함
  • 톰캣은 내부에 Apache Web Server(이하 웹서버)와 서블릿 컨테이너를 소유하고 있음
  • 하나의 서블릿 컨테이너에는 하나의 Web Application이 존재하고 있음, 하나의 톰캣에는 하나의 서블릿 컨테이너, 하나의 JVM
  • 이로 인해 톰캣은 HTTP 요청을 웹서버로 받고, 웹서버는 서블릿 컨테이너에 해당 요청을 전달, 서블릿 컨테이너는 받은 요청을 보유한 서블릿과 매핑하여 응답을 전달함
여기서 잠깐, Servlet Context

  • 하나의 톰캣 내에 여러 서블릿이 존재할 수 있음
  • 서블릿 컨테이너는 HTTP 요청이 들어오면 새로운 쓰레드를 생성함
  • 각 서블릿의 정보는 Servlet Context(이하 서블릿 컨텍스트)에 공유 되며, 서블릿 컨텍스트 메소드를 통해 init(), service(), destroy()로 서블릿 Life-Cycle(생명주기)를 관리함

Spring MVC 이전

  • 서블릿을 통해 개발자는 HTTP 요청/응답을 처리할 수 있었지만, 서블릿의 설정과 생명주기, HTML 등을 직접 관리해야했기 때문에 굉장히 불편했음
  • 이를 개선하기 위해 Java Server Page(이하 JSP)가 탄생했지만, JSP는 페이지와 비즈니스 로직이 동시에 존재하는 치명적 단점이 존재했고, 객체지향 원칙 중 하나인 Single-responsibility principle(이하 SRP)를 어기게 되었음
  • SRP를 지키기 위해 페이지, 비즈니스 로직, 데이터를 각각 View, Controller, Model로 분리하는 MVC 패턴이 탄생함

Spring MVC의 구조

MVC 1

  • 초기 스프링 MVC의 구조는 MVC 1이라고 하는 구조를 띄었음
  • JSP내에서 비즈니스 로직이 분리되었지만 여전히 ViewController가 JSP내에 동시에 있었기 때문에 프로그램이 커질수록 굉장히 복잡하고, JSP 내에 로직이 결합되어 있어 유지보수성이 최악이었음

MVC 2

  • MVC 1 패턴을 개선하여 MVC 2 패턴이 나왔고, 스프링 위원회가 채택하며 현재의 스프링 MVC는 MVC 2 패턴을 이야기 함
  • MVC 1 패턴과 달리 MVC 2 패턴은 View, Controller가 분리되어 각 서비스 별로 수정이 가능함
  • 스프링 MVC는 org.springframework.spring-webmvc라는 이름의 라이브러리로 구현되어 있음

Spring MVC의 동작

Spring MVC의 특징

  • 스프링 MVC의 가장 큰 특징은 DispatcherServlet(이하 디스패처 서블릿)을 사용한 Front-Controller 패턴으로 각 컨트롤러 별 공통된 로직을 추출하여 필터링하고, 각 컨트롤러에 작업을 분배하는 역할을 수행
    • 스프링의 MVC2 준수와 디스패처 서블릿의 동작

Spring MVC의 실행

  • 스프링 MVC의 실행은 크게 디스패처 서블릿으로의 인입, 각 컨트롤러로 분배, 서비스 호출로 이루어짐
Dispatcher Servlet
  • 클라이언트로부터 받은 요청을 모아 필터링 및 전처리 후 각 요청 URL에 맞는 Mapping Handler에게 요청을 보냄
Handler Mapping
  • 요청 URL과 매핑된 핸들러를 선택하는 전략
  • 여러 매핑 방법이 있지만 일반적으로 RequestMappingHandlerMapping 인터페이스를 구현한 @RequestMapping 을 사용함
Handler Adapter
  • 디스패처 서블릿에 핸들러를 매핑할 수 있는 인터페이스 구현체
  • 위와 동일하게 @RequestMapping 어노테이션을 처리할 수 있는 RequestMappingHandlerAdapter를 일반적으로 사용함
View Resolver
  • View에서 View 오브젝트 자체가 아닌 View의 이름만을 사용하는 방식
  • InternalResourceViewResolver 인터페이스 구현체를 이용하여 View 이름을 통해 ModelAndView 객체로 변환

동작 순서

  • 위와 같은 구현체들을 통해 실제 스프링 MVC의 동작은 다음과 같이 이루어짐
  1. 핸들러 조회: 핸들러 매핑을 통해 요청 URL에 매핑된 핸들러(컨트롤러)를 조회
  2. 핸들러 어댑터 조회: 핸들러를 실행할 수 있는 핸들러 어댑터를 조회
  3. 핸들러 어댑터 실행: 핸들러 어댑터를 실행
  4. 핸들러 실행: 핸들러 어댑터가 실제 핸들러를 실행
  5. ModelAndView 반환: 핸들러 어댑터는 핸들러가 반환하는 정보를 ModelAndView로 변환해서 반환
  6. viewResolver 호출: viewResolver를 찾고 실행
  • 이 때 JSP라면 InternalResourceViewResolver가 자동 등록 및 실행
  1. View 반환: viewResolver는 뷰의 논리 이름을 물리 이름으로 바꾸고, 렌더링 역할을 담당하는 뷰 객체를 반환
  • JSP의 경우 InternalResourceView(JstlView)를 반환하는데, 내부에 forward() 로직이 존재
  1. 뷰 렌더링: 뷰를 통해서 뷰를 렌더링 한다

0개의 댓글