개발 내용을 기준으로 정리한 내용을 작성해보겠다.
기존에 웹 서비스를 개발 할 때 사용되던 서블릿과 JSP는 다음과 같은 한계가 있었다.
서블릿과 JSP의 한계
- 서블릿
- 서블릿으로 개발할 때는 사용자에게 표시되는 화면이 자바 코드에 섞여서 지저분하고 복잡했다.
- JSP
- JSP를 사용하면서 HTML 작업을 깔끔하게 가져갈 수 있었고 중간중간 동적으로 변경이 필요한 부분에만 자바 코드를 적용할 수 있었다.
- 하지만 JSP를 살펴보았을 때 반은 회원을 저장, 관리하기 위한 비즈니스 로직이었고
나머지 반은 결과를 표시하기 위한 뷰 영역이였다. - 즉 비즈니스 로직 또한 모두 JSP에 노출되어 있다는 말이되고
JSP가 너무 많은 역할을 하고 있는 것을 볼 수 있다. - 이는 유지보수에도 너무 큰 수고가 들어가기에 문제가 될 수도 있다.
⇒ 이와 함께 MVC 패턴이 등장하게 되었다.
MVC 패턴
- 하나의 서블릿이나 JSP로 처리하던 것을 컨트롤러, 뷰라는 영역으로 서로 역할을 나눈 것을 말한다.
- 컨트롤러
- HTTP 요청을 받아서 파라미터를 검증하고, 비즈니스 로직을 실행한다.
- 뷰에 전달할 결과 데이터를 조회해서 모델에 담는다.
- 모델
- 뷰에 전달할 데이터를 담아두는 역할이다.
- 뷰가 필요한 데이터를 모두 모델에 담아둠으로써 뷰가 원하는 데이터는 모델에서모두 찾을 수 있게 된다.
- 뷰
- 모델에 담겨져있는 데이터를 통해서 화면을 그리는 일에 집중한다.
- 컨트롤러
아래와 같은 문제들을 해결할 수 있다.
- 너무 많은 역할을 떠맡지 않게 해야한다.
- 비즈니스 로직은 서블릿 처럼 다른 곳에서 처리
- JSP는 목적에 맞게 HTML로 화면을 그리는 일에 집중하게 처리
- 변경의 라이프 사이클이 다르다.
- MVC 패턴이 아니라면 한 코드에 비즈니스 로직과 뷰가 모두 들어가있게되는데,
각각의 요소를 수정하는 하는 시기가 다를 가능성이 매우 크다. - 비즈니스 로직을 수정하고 싶어도 뷰를 함께봐야되고, 뷰를 수정하고 싶어도 비즈니스 로직을 함께 봐야되기 때문에 유지보수면에서 매우 좋지 않다.
- MVC 패턴이 아니라면 한 코드에 비즈니스 로직과 뷰가 모두 들어가있게되는데,
- 기능이 특화되어 있다.
- JSP 같은 뷰 템플릿은 화면을 렌더링하는데 특화되어 있기에 그 부분의 업무만 담당하는 것이 효과적이다.
- Repository, Service는 무엇인가?
- 위처럼 MVC 패턴을 이용하면 비즈니스 로직과 뷰는 분리가 된다.
- 하지만, 컨트롤러에서는 HTTP 연결을 담당하는 컨트롤러 로직이 있기 때문에
컨트롤러가 너무 많은 일을 담당하게 된다.
- Service, Repository로 나누기
- 위 처럼 비즈니스 로직만을 다루는 Service, Repository 계층을 따로 만들어서
Controller는 컨트롤러 로직에만 집중할 수 있게한다. - 우리가 아까까지 만든 코드에서 Service가 없었던 이유는 비즈니스 로직이 간단하기 때문에 Repository로만 사용한 것이다.
- 위 처럼 비즈니스 로직만을 다루는 Service, Repository 계층을 따로 만들어서
MVC 패턴의 한계 (컨트롤러의 문제)
- MVC 패턴을 이용해서 뷰를 렌더링 하는 역할을 확실히 구분할 수 있게 되었다.
- 하지만 컨트롤러의 경우는 중복되는 코드가 많고 몇가지 문제가 있다.
- ViewPath 선언 및 forward() 중복
- 사용되지 않는 코드 (request, response)
- 공통 처리가 힘들다.
- 공통 처리 메서드를 만들어도 그 메서드를 항상 호출해야하며,
복잡해질 수록 공통으로 처리해야하는 부분이 너무 많아질 것이다.
- 공통 처리 메서드를 만들어도 그 메서드를 항상 호출해야하며,
⇒ 이를 위해서 프론트 컨트롤러 (Front Controller) 를 이용하여 공통 처리를 한다.
프론트 컨트롤러 (Front Controller)
- 공통 처리를 전문으로 해주는 컨트롤러를 프론트 컨트롤러라고 한다.
- 프론트 컨트롤러 서블릿 하나로 클라이언트의 요청을 받는다.
- 프론트 컨트롤러가 요청에 맞는 컨트롤러를 찾아서 호출한다.
- 프론트 컨트롤러를 제외한 나머지 컨트롤러는 서블릿을 사용하지 않아도 되는 것이다.
- 스프링 웹 MVC와 프론트 컨트롤러
- 결국엔 스프링 웹 MVC의 핵심도 Frontcontroller이다.
- DispatcherServlet이 FrontController의 패턴으로 구현되어 있다.
스프링 MVC
- 위에서 설명했던 것 처럼 DispatcherServlet이 FrontController의 역할을 하고있다.
- 스프링 부트는 실행될 때 컨트롤러들을 찾아 등록을 해준다.
- RequestMappingHandlerMapping
- @Controller가 붙은 핸들러(컨트롤러)를 찾아 매핑한다.
- BeanNameUrlHandlerMapping
- 스프링 빈으로 등록된 이름으로 핸들러를 찾아 매핑한다.
- RequestMappingHandlerMapping
- 핸들러를 찾아서 해당 핸들러를 처리할 수 있는 핸들러 어댑터를 찾게된다.
- RequestMappingHandlerAdapter
- @RequestMapping과 같은 어노테이션 기반의 컨트롤러를 처리한다.
- HttpRequestHandlerAdapter
- HttpRequestHandler를 처리한다. (이전에 만들었던 서블릿과 비슷)
- SimpleControllerHandlerAdapter
- 옛날에 사용되던(가장 간단한) 컨트롤러를 처리한다.
- RequestMappingHandlerAdapter
- 찾아온 핸들러 어댑터로 핸들러를 실행하게된다.
- 그러면서 매핑해두었던 컨트롤러를 실행하게되고, ModelandView를 반환하게된다.
- 반환한 Model과 View정보를 가지고 viewResolver에서 정확한 ViewPath를 반환해준다.
- 그 후 렌더링을 통해 HTML 응답을 하게 된다.
이렇게 스프링 MVC가 어떻게 작동되는지 살펴보았다.
참고 -
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1
'Spring' 카테고리의 다른 글
[SpringMVC] 매핑 (Mapping) (0) | 2022.05.23 |
---|---|
[SpringMVC] 로깅 (Logging) (0) | 2022.05.23 |
[Spring MVC] HTML, HTTP API, CSR, SSR (0) | 2022.05.11 |
[Spring MVC] 웹 애플리케이션 (0) | 2022.04.25 |
[Spring 핵심 원리] 빈 스코프와 DL(Dependency Lookup) (0) | 2022.03.20 |