스프링 MVC
Spring MVC는 Spring Framework에서 제공하는 웹 애플리케이션 개발을 위한 모듈입니다. MVC는 `Model-View-Controller`의 약자로, 애플리케이션의 구조를 이 세 가지 역할로 분리하여 개발하는 디자인 패턴입니다. Spring MVC는 Model, View, Controller를 모듈화하여 개발할 수 있기 때문에 유지보수성과 확장 가능성이 좋아집니다.
스프링 MVC는 `프런트 컨트롤러 패턴` 아키텍처를 사용합니다.
`프런트 컨트롤러 패턴`은 클라이언트 모든 요청을 `프런트 컨트롤러`라는 컴포넌트가 받아 중앙 집중적으로 처리하는 디자인 패턴입니다. 공통적인 처리를 `프런트 컨트롤러`에 통합할 수 있기때문에 핸들러에서 처리하는 내용을 줄일 수 있다는 장점이 있습니다.
프런트 컨트롤러(DispatcherServlet)의 기능
- 요청의 분배
클라이언트의 요청을 받아들이고, 해당 요청을 처리할 `핸들러(컨트롤러)`에게 전달합니다. `DispatcherServlet`은 요청의 경로와 등록된 핸들러 매핑을 기반으로 어떤 핸들러가 요청을 처리해야 하는지 판단합니다. - 핸들러 실행
`DispatcherServlet`은 적절한 핸들러를 찾아 호출합니다. 핸들러는 비즈니스 로직을 수행하고, 요청에 대한 처리를 담당합니다. 핸들러는 `@Controller` 어노테이션이 지정된 클래스로 정의되며, 메서드에는 `@RequestMapping` 등의 어노테이션을 사용하여 요청과 매핑됩니다. - 데이터 바인딩
`DispatcherServlet`은 클라이언트의 요청 파라미터를 핸들러의 메서드 파라미터와 바인딩합니다. 이를 통해 요청 파라미터를 객체로 변환하거나, 폼 데이터를 처리하는 등의 작업을 수행할 수 있습니다. - 모델과 뷰 관리
핸들러는 비즈니스 로직 수행 후, 결과 데이터를 모델에 저장합니다. `DispatcherServlet`은 이 모델을 적절한 뷰로 전달하기 위해 `View Resolver`를 사용하여 뷰를 찾습니다. 뷰는 결과 데이터를 가지고 실제 응답을 생성하는 역할을 합니다. - 인터셉터 처리
`DispatcherServlet`은 핸들러 실행 전후에 `인터셉터`를 적용합니다. 인터셉터는 요청 전후에 추가적인 로직을 수행하며, 요청의 처리를 중단하거나 추가 데이터를 추가할 수 있습니다. 인터셉터는 요청의 보안, 로깅, 캐싱 등 다양한 측면에서 유용하게 사용됩니다.
프런트 컨트롤러 설정: @EnableWebMvc
`@EnableWebMvc` 어노테이션은 Spring MVC를 사용하기 위해 필요한 설정을 활성화하는 역할을 합니다. 이 어노테이션을 사용하지 않으면 기본적인 Spring Framework 설정만으로는 Spring MVC를 사용할 수 없습니다.
- 자바 기반 설정 방식
: 설정 클래스에 `@EnableWebMvc` 추가 - XML 파일 사용 방식
: `<mvc:annotation-driven>` 요소 추가
- 핸들러 매핑과 핸들러 어댑터 등의 빈 등록: Spring MVC에서는 요청을 처리하기 위해 핸들러 매핑과 핸들러 어댑터가 필요합니다. @EnableWebMvc를 사용하면 이러한 빈들이 자동으로 등록되어 요청 처리를 위한 기본적인 설정을 할 수 있습니다.
- 기본 리소스 핸들러 등록: Spring MVC는 정적 리소스 (CSS, JavaScript, 이미지 등)에 대한 요청을 처리하기 위해 리소스 핸들러를 등록해야 합니다. @EnableWebMvc를 사용하면 기본 리소스 핸들러를 등록하여 정적 리소스 요청을 처리할 수 있습니다.
- 기타 웹 관련 설정 활성화: @EnableWebMvc는 Spring MVC에서 사용하는 다양한 웹 관련 설정을 활성화합니다. 예를 들어, HTTP 메시지 컨버터, 컨트롤러 어드바이스, 예외 처리 등의 설정을 사용할 수 있게 됩니다.
프런트 컨트롤러 구조
- `DispatcherServlet` 클래스는 클라이언트의 요청을 받습니다.
- `DispatcherServlet` 클래스는 `HandlerMapping` 인터페이스의 `getHandler` 메소드를 호출해서 요청과 매칭되는 `Handler(Controller)`를 가져옵니다.
- `DispatcherServlet` 클래스는 `Handler(Controller) `에 대응되는 `HandlerAdapter`를 찾고 `HandlerAdapter` 인터페이스의 `handle` 메소드를 호출해서 `Handler(Controller)` 객체의 메소드 호출을 의뢰합니다.
- `Handler(Controller)`는 비즈니스 로직을 수행하고, 결과 데이터를 `HandlerAdapter`에 반환합니다.
- `DispatcherServlet` 클래스는 `ViewResolver`에게 결과 데이터와 함께 뷰 이름을 전달합니다.
- `ViewResolver` 클래스의 `resolveViewName` 메소드를 호출해서 `Handler` 객체에서 반환된 뷰 이름에 대응하는 `View` 인터페이스 객체를 가져온다.
- `DispatcherServlet` 클래스는 `View` 인터페이스의 `render` 메소드를 호출해서 응답 데이터에 대한 렌더링을 요청한다. `View` 인터페이스의 구현 클래스는 JSP와 같은 템플릿 엔진을 사용해 렌더링할 데이터를 생성한다.
- `DispatcherServlet` 클래스는 클라이언트에 응답을 반환한다.
DispatcherServlet
DispatcherServlet은 Spring MVC의 핵심으로서 클라이언트의 모든 요청을 받아서 적절한 핸들러에게 전달합니다. 클라이언트로부터 요청을 받으면 DispatcherServlet은 HandlerMapping에게 요청을 전달하여 어떤 핸들러가 해당 요청을 처리할지 찾습니다. 그리고 찾은 핸들러를 HandlerAdapter에게 전달하여 실행합니다. 실행된 결과를 받아서 응답을 생성하고 클라이언트에게 반환합니다.
위 설명에는 하지 않았지만 `DispathcerServlet`의 역할을 하기 위한 여러가지 인터페이스들이 더 있습니다.
- HandlerExceptionResolver: 예외처리를 하기 위한 인터페이스 (스프링 MVC에서 구현 클래스 제공)
- LocaleResolver, LocaleContextResolver: 클라이언트의 Locale 정보를 확인하기 위한 인터페이스 (스프링 MVC에서 구현 클래스 제공)
- HandlerInterceptor: 핸들러 실행 전후에 하는 공통 처리를 구현하기 위한 인터페이스 (개발자 직접 구현)
- etc.
Handler
Handler는 DispatcherServlet이 요청을 처리하기 위해 실행하는 핸들러입니다. 핸들러는 클라이언트의 요청을 실제로 처리하고, 해당 요청에 대한 비즈니스 로직을 실행하는 역할을 담당합니다.
프레임워크 관점에선 `핸들러(Handler)`라 하지만 개발자가 작성하는 클래스의 관점에선 `컨트롤러(Controller)`이라 불리며, 사용자의 요청을 받아서 처리하고 응답을 생성합니다.
개발자가 Controller를 구현하는데 있어서 예전에는 Controller 인터페이스의 구현 클래스를 작성하고 `handleRequest`를 구현하는 방식이었다면, 요즘은 `@Controller`어노테이션을 지정하고 요청 처리를 수행하는 메서드에 `@RequestMapping`을 지정한 클래스를 작성하는 방식이 사용됩니다.
HandlerMapping
HandlerMapping은 DispatcherServlet이 요청을 받았을 때 어떤 핸들러가 해당 요청을 처리할지 결정하는 역할을 담당합니다. HandlerMapping은 `URL`과 `핸들러(Controller)` 사이의 `매핑`을 관리하며, 요청 URL을 기반으로 적절한 핸들러를 찾아서 반환합니다. Spring MVC에서는 여러 가지 HandlerMapping 구현체가 제공되며, 주요한 것으로는 AnnotationMethodHandlerMapping, RequestMappingHandlerMapping, DefaultAnnotationHandlerMapping 등이 있습니다.
예를 들어, RequestMappingHandlerMapping 클래스는 `@RequestMapping`에 정의된 설정 정보를 바탕으로 실행할 핸들러를 선택합니다.
HandlerAdapter
HandlerAdapter는 DispatcherServlet이 찾은 핸들러를 실행하기 위해 필요한 메서드를 호출하는 역할을 담당합니다. HandlerAdapter는 핸들러(Controller)의 종류에 따라 적절한 실행 방식을 선택하고, 핸들러와 관련된 메서드를 호출하여 요청을 처리합니다. 그후, 메서드의 처리 결과를 반환값으로 되돌려보냅니다.
Spring MVC에서는 여러 가지 HandlerAdapter 구현체가 제공되며, 주요한 것으로는 AnnotationMethodHandlerAdapter, RequestMappingHandlerAdapter, HttpRequestHandlerAdapter 등이 있습니다.
이때 매개변수나 반환값을 다루거나 처리할 때 유연하게 하기 위해 두 가지 인터페이스를 제공합니다.
- HandlerMethodArgumentResolver: 핸들러 메소드 매개변수에 전달하는 값을 다루기 위한 인터페이스
- HandlerMethodReturnValueHandler: 핸들러 메소드에서 반환된 값을 처리하기 위한 인터페이스
ViewResolver
핸들러에서 반환한 뷰(View) 이름을 보고, 이후에 사용할 View 인터페이스의 구현 클래스를 선택하는 역할을 합니다. 클라이언트에게 반환될 뷰의 이름을 기반으로 실제로 렌더링될 뷰 객체를 찾아서 반환합니다. ViewResolver는 뷰의 경로, 확장자, 템플릿 엔진 등의 설정을 기반으로 적절한 뷰 객체를 찾아서 반환합니다.
View
View는 Spring MVC에서 뷰의 표현을 담당하는 객체입니다. 뷰는 클라이언트에게 반환될 결과 화면을 생성하고 렌더링하는 역할을 수행합니다. Spring MVC는 다양한 종류의 뷰를 지원하며, JSP, Thymeleaf, Freemarker, Velocity 등 다양한 템플릿 엔진을 사용할 수 있습니다. 각각의 뷰는 템플릿 엔진에 의해 동적으로 렌더링되어 최종 결과를 생성합니다.
※ ViewResolver는 뷰 이름을 받아서 실제로 렌더링될 뷰 객체를 찾아주는 역할을 하며, View는 실제로 결과 화면을 생성하고 렌더링하는 역할을 합니다. 이를 통해 Spring MVC는 개발자가 논리적인 뷰 이름을 사용하여 간단하게 결과 화면을 생성하고, 다양한 템플릿 엔진과의 통합을 제공할 수 있습니다.
'Spring Framework' 카테고리의 다른 글
Spring Model 객체: 컨트롤러에서 뷰로 데이터 전달 (0) | 2022.09.06 |
---|---|
Spring @RequestMapping과 이에 대한 속성 (0) | 2022.09.05 |
Spring Cookie와 Session (로그인 유지 예제) (0) | 2022.09.01 |
Spring 공통적인 작업 처리를 위한 HandlerInterceptor (0) | 2022.09.01 |
Spring 다국어 적용하는 방법들 (0) | 2022.08.31 |