본문 바로가기
Spring

Spring | Spring MVC 패턴 - MVC와 서블릿 (1)

by Hoya324 2024. 9. 5.

MVC 패턴의 등장

서블릿과 JSP의 한계

  • 서블릿으로 개발할 때는 뷰(View)화면을 위한 HTML을 만드는 작업이 자바 코드에 섞여서 지저분하고 복잡했다.
  • JSP를 사용한 덕분에 뷰를 생성하는 HTML 작업을 깔끔하게 가져가고, 중간중간 동적으로 변경이 필요한 부분에만 자바 코드를 적용했다.
  • 그러나 JSP를 사용할 때에도 프로젝트의 규모가 커지면서 불편함을 겪게 된다.
  • JAVA 코드, 데이터를 조회하는 리포지토리 등등 다양한 코드가 모두 JSP에 노출되어 있다.
  • JSP가 너무 많은 역할을 한다. 수백 수천줄이 넘어가는 JSP를 떠올려보면 정말 지옥과 같을 것이다.

MVC 패턴 개요

MVC 전의 문제 유지보수가 어려움

  • 너무 많은 역할 하나의 서블릿이나 JSP만으로 비즈니스 로직과 뷰 렌더링까지 모두 처리하게 되면, 너무 많은 역할을 하게되고, 결과적으로 유지보수가 어려워진다.
  • 비즈니스 로직을 호출하는 부분에 변경이 발생해도 해당 코드를 손대야 하고, UI를 변경할 일이 있어도 비즈니스 로직이 함께 있는 해당 파일을 수정해야 한다.
  • HTML 코드 하나 수정해야 하는데, 수백줄의 자바 코드가 함께 있으면 굉장히 복잡해진다.

변경 사이클이 다름

  • JSP와 서블릿 사이에 변경의 라이프 사이클이 다르다는 점이다.
  • 예를 들어서 UI 를 일부 수정하는 일과 비즈니스 로직을 수정하는 일은 각각 다르게 발생할 가능성이 매우 높고 대부분 서로에게 영향을 주지 않는다.
  • 이렇게 변경의 라이프 사이클이 다른 부분을 하나의 코드로 관리하는 것은 유지보수하기 좋지 않다. (물론 UI가 많이 변하면 함께 변경될 가능성도 있다.)
  • JSP 같은 뷰 템플릿은 화면을 렌더링 하는데 최적화 되어 있기 때문에 이 부분의 업무만 담당하는 것이 가장 효과적이다.

Model View Controller

  • MVC 패턴은 하나의 서블릿이나, JSP로 처리하던 것을 컨트롤러(Controller)와 뷰(View)라는 영역으로 서로 역할을 나눈 것을 말한다.
  • 웹 애플리케이션은 보통 이 MVC 패턴을 사용한다.

Controller

  • HTTP 요청을 받아서 파라미터를 검증하고, 비즈니스 로직을 실행한다.
  • 그리고 뷰에 전달할 결과 데이터를 조회해서 모델에 담는다.

Model

  • 뷰에 출력할 데이터를 담아둔다.
  • 뷰가 필요한 데이터를 모두 모델에 담아서 전달해주는 덕분에 뷰는 비즈니스 로직이나 데이터 접근을 몰라도 되고, 화면을 렌더링 하는 일에 집중할 수 있다.

View

  • 모델에 담겨있는 데이터를 사용해서 화면을 그리는 일에 집중한다.
  • HTML을 생성하는 부분을 말한다.

참고

컨트롤러에 비즈니스 로직을 둘 수도 있지만, 이렇게 되면 컨트롤러가 너무 많은 역할을 담당한다.

그래서 일반적으로 비즈니스 로직은 서비스(Service)라는 계층을 별도로 만들어서 처리한다.

그리고 컨트롤러는 비즈니스 로직이 있는 서비스를 호출하는 역할을 담당한다.

참고로 비즈니스 로직을 변경하면 비즈니스 로직을 호출하는 컨트롤러의 코드도 변경될 수 있다.

Layered Architecture

  • Layered Architecture는 관심사를 분리해서 Layer들로 나누고 Layer 내부에 관련되거나 유사한 구성요소들을 배치함으로써 Layer간의 종속성을 저하시켜 Layer의 격리를 통한 이점을 만들어내는 Architecture이다.
  • Layer의 내부의 구성 요소가 되는 것이 MVC 패턴이다.

Web Layer(Presentation Layer)

  • 흔히 사용하는 Controller와 JSP/freemarker 등 View 템플릿 영역이다.
  • 이외에도 Filter, Intercepter, ControllerAdvice등 외부 요청과 응답에 대한 전반적인 영역을 말한다.

Service Layer(Business Layer)

  • 일반적으로 Controller와 Dao의 중간 영역에서 사용된다.
  • @Transactional 이 사용되어야 하는 영역이다.
  • 보통 여기서 비즈니스 로직을 처리하나 관점에 따라 Domain Model에서 비즈니스 로직을 처리하기도 한다.

Dtos

  • 계층 간에 데이터 교환을 위한 객체

Domain Model(Business Layer)

  • 도메인이라 불리는 개발 대상을 모든 사람이 동일한 관점에서 이해할 수 있고 공유할 수 있도록 단순화 시킨 것을 도메인 모델이라고 한다.
    • ex) 택시 앱 -> 배차, 탑승, 요금 등이 모두 도메인이 될 수 있다.
  • @Entity 가 사용된 영역이 도메인 모델이다.

Layered Architecture와 MVC의 차이점

  • Model은 데이터와 관련된 부분이다. 데이터와 비즈니스 로직을 관리한다.
    • 비즈니스 로직에 맞춰서 데이터를 처리하는 Business(Domain) Layer에 속할 것이다.
  • View는 사용자에게 보여지는 부분이다.
    • 그렇기에 사용자와의 상호작용을 통해서 정보를 표시해주고 정보를 가져오는 Presentation Layer에 속할 것이다.
  • Controller는 사용자의 입력된 Domain을 DTO로 변환하는 등의 처리하고 Model과 View를 이어줘야 하기 때문에 Presentation Layer에 속할 것이다.

서블릿

서블릿이란

  • 서블릿(Servlet)이란 동적 웹 페이지를 만들 때 사용되는 자바 기반의 웹 애플리케이션 프로그래밍 기술이다.
  • 서블릿은 웹 요청과 응답의 흐름을 간단한 메서드 호출만으로 체계적으로 다룰 수 있게 해준다.
  • 서블릿은 서버에서 실행되다가 웹 브라우저에서 요청을 하면 해당 기능을 수행한 후 웹 브라우저에 결과를 전송한다.
  • 쉽게 예를들면 로그인 시도를 할 때, 서버가 클라이언트에서 입력되는 아이디와 비밀번호를 확인하고 결과를 응답하는데 이러한 역할을 수행하는 것이 서블릿이다.

특징

  • 클라이언트의 Request에 대해 동적으로 작동하는 웹 어플리케이션 컴포넌트
  • 기존의 정적 웹 프로그램의 문제점을 보완하여 동적인 여러 가지 기능을 제공
  • JAVA의 스레드를 이용하여 동작
  • MVC패턴에서 컨트롤러로 이용됨
  • 컨테이너에서 실행
  • 보안 기능을 적용하기 쉬움

서블릿 동작과정

  • 클라이언트가 웹 서버에 요청하면 웹 서버는 그 요청을 톰캣과 같은 WAS에 위임한다.
  • 그러면 WAS는 각 요청에 해당하는 서블릿을 실행한다.
  • 그리고 서블릿은 요청에 대한 기능을 수행한 후 결과를 반환하여 클라이언트에 전송한다.

서블릿의 생명주기

  • 서블릿도 자바 클래스이므로 실행하면 초기화부터 서비스 수행 후 소멸하기까지의 과정을 거친다.
  • 이 과정을 서블릿의 생명주기라하며 각 단계마다 호출되어 기능을 수행하는 콜백 메서드를 서블릿 생명주기 메서드라한다.

서블릿 컨테이너

  • 서블릿 컨테이너란, 구현되어 있는 servlet 클래스의 규칙에 맞게 서블릿을 담고 관리해주는 컨테이너다.
  • 클라이언트에서 요청을 하면 컨테이너는 HttpServletRequest, HttpServletResponse 두 객체를 생성하여 post, get여부에 따라 동적인 페이지를 생성하여 응답을 보낸다.

웹서버와의 통신 지원

  • 서블릿 컨테이너는 서블릿과 웹서버가 손쉽게 통신할 수 있게 해준다.
  • 일반적으로 소켓을 만들고 listen, accept 등을 해야하지만 서블릿 컨테이너는 이러한 기능을 API로 제공하여 복잡한 과정을 생략할 수 있게 해준다.
  • 그래서 개발자가 서블릿에 구현해야 할 비지니스 로직에 대해서만 초점을 두게끔 도와준다.

서블릿 생명주기 관리

  • 서블릿 컨테이너는 서블릿 클래스를 로딩하여 인스턴스화하고, 초기화 메소드를 호출하고, 요청이 들어오면 적절한 서블릿 메소드를 호출한다.
  • 또한 수명이 다 된 서블릿을 적절하게 가비지 콜렉터를 호출하여 필요없는 자원 낭비를 막아준다.

멀티쓰레드 지원 및 관리

  • 서블릿 컨테이너는 Request가 올 때마다 새로운 자바 쓰레드를 하나 생성하는데, HTTP 서비스 메소드를 실행하고 나면, 쓰레드는 자동으로 죽게 된다.
  • 원래는 쓰레드를 관리해야 하지만 서버가 다중 쓰레드를 생성 및 운영해주니 쓰레드의 안정성에 대해서 걱정하지 않아도 된다.

선언적인 보안 관리

  • 서블릿 컨테이너를 사용하면 개발자는 보안에 관련된 내용을 서블릿 또는 자바 클래스에 구현해 놓지 않아도 된다.
  • 일반적으로 보안관리는 XML 배포 서술자에다가 기록하므로, 보안에 대해 수정할 일이 생겨도 자바 소스 코드를 수정하여 다시 컴파일 하지 않아도 보안관리가 가능하다.

다음 게시물

Spring | Spring MVC 패턴 - HTTP 요청을 받고 응답하기까지의 전 과정(2)