Front Controller Pattern architecture
Spring MVC는 '프론트 컨트롤러 패턴(Front Controller)'이라고 하는 아키텍처를 채택하고 있다.
프론트 컨트롤러 패턴은 클라이언트 요청을 프론트 컨트롤러라는 컴포넌트가 받아 요청 내용에 따라 수행하는
핸들러(Handler)를 선택하는 아키텍처다.
프론트 컨트롤러 패턴은 공통적인 처리를 프론트 컨트롤러에 통합할 수 있어서 핸들러에서 처리하는 내용을
줄일 수 있다.
Spring MVC 아키텍처에서는 다음과 같은 기능들을 프론트 컨트롤러가 대행해주고 있다.
● 클라이언트의 요청 접수
● 요청 데이터를 자바 객체로 변환
● 입력값 검사 실행(Bean Validation)
● 핸들러 호출
● 뷰 선택
● 클라이언트에 요청 결과 응답
● 예외처리
Spring MVC의 프론트 컨트롤러는 org.springfarmework.web.servlet.DispatcherServlet 클래스(서블릿)로
구현되어 있으며, 다음과 같은 흐름으로 처리를 수행한다.
1. DispatcherServlet 클래스는 클라이언트의 요청을 받는다.
2. DIspatcherServlet 클래스는 HandlerMapping 인터페이스의 getHandler 메서드를 호출해서 요청 처리를 하는
Handler 객체(컨트롤러)를 가져온다.
3. DispatcherServlet 클래스는 HandlerAdapter 인터페이스의 handle 메서드를 호출해서 Handler 객체의 메서드
호출을 의뢰한다.
4. HandlerAdapter 인터페이스 구현 클래스는 Handler 객체에 구현된 메서드를 호출해서 요청 처리를 수행한다.
5. DispatcherServlet 클래스는 ViewResolver 인터페이스의 resolveViewName 메서드를 호출해서 Handler 객체에서
반환된 뷰 이름에 대응하는 View 인터페이스 객체를 가져온다.
6. DispatcherServlet 클래스는 View 인터페이스의 render메서드를 호출해서 응답 데이터에 대한 렌더링을 요청한다.
View 인터페이스의 구현 클래스에는 JSP와 같은 템플릿 엔진을 사용해 렌더링할 데이터를 생성한다.
7. DispatcherServlet 클래스는 클라이언트에 응답을 반환한다.
위의 흐름도를 보면 프론트 컨트롤러의 처리 내용 대부분이 인터페이스를 통해 실행되고 있음을 알 수 있다.
이는 Spring MVC가 가진 특징 중 하나로 인터페이스를 통해 프레이무어크의 기능을 확장할 수 있다는 것을
알 수 있다.
이 외에도 프레임워크가 동작하는데 사용되는 다양한 인터페이스가 준비되어 있다.
프론트 컨트롤러를 구성하는 컴포넌트
DispatcherServlet
프론트 컨트롤러와 연동되는 진입점 역할을 하며 기본적인 처리 흐름을 제어하는 사령탑 역할을 한다.
다음 표에서 설명하는 인터페이스와도 연동되어 프레임워크의 전체 기능을 완성한다.
인터페이스명 |
역할 |
HandlerExceptinoResolver |
예외처치를 하기 위한 인터페이스다. Spring MVC가 제공하는 기본 구현 클래스가 적용되어 있다. |
LocaleResolver, LocaleContextResolver |
클라이언트의 로컬정보를 확인하기 위한 인터페이스다. Spring MVC가 제공하는 기본 구현 클래스가 적용되어 있다. |
ThemeResolver |
클라이언트의 테마(UI)를 결정하기 위한 인터페이스다. Spring MVC가 제공하는 기본 구현 클래스가 적용되어 있다. |
FlashMapManager |
FlashMap 이라는 객체를 관리하기 위한 인터페이스다. FlashMap은 PRG(Post Redirect Get) 패턴의 Redirect와 Get사이에서 모델을 공유하기 위한 Map객체다. Spring MVC에서 제공하는 기본 구현 클래스가 적용되어 있다. |
RequestToViewNameTraslator |
핸들러가 뷰 이름과 뷰를 반환하지 않은 경우에 적용되는 뷰 이름을 해결하기 위한 인터페이스다. Spring MVC에서 제공하는 기본 구현 클래스가 적용되어 있다. |
HandlerInterceptor |
핸들러 실행 전후에 하는 공통 처리를 구현하기 위한 인터페이스다. 이 인터페이스는 애플리케이션 개발자가 구현하고 Spring MVC에 등록해서 사용할 수 있다. |
MultipartResolver |
멀티파트 요청을 처리하기 위한 인터페이스다. Spring MVC에서 몇가지 구현클래스가 제공되고 있지만 기본적으로 적용되지 않는다. |
Handler
Spring MVC에서 하는 일은 프론트 컨트롤러가 받은 요청에 따라 필요한 처리를 수행하는 것이다.
프레임워크 관점에서는 핸들러라고 부르지만 개발자가 작성하는 클래스 관점에서는 컨트롤러라고 부른다.
Spring MVC에서는 다음 두가지 방법으로 컨트롤러를 구현할 수 있다.
● @Controller 어노테이션(org.springframework.stereotype.Controller)을 클래스에 지정하고 요청 처리를 수행하는
메서드에 @RequestMapping을 지정한 클래스를 작성한다.
@Controller
public class WelcomeController {
@RequestMapping("/")
public String home(Model model) {
model.addAttribute("now", new Date());
return "home";
}
}
● org.springframework.web.servlet.mvc.Controller 인터페이스의 구현 클래스를 작성하고 요청을 처리할
메서드(handleRequest)를 구현한다.
Spring Framework 3.0.0 이전부터 지원되는 전통적인 구현방법으로 예전부터 Spring을 사용해온 개발자에게는
친숙한 방법이지만 신규 애플리케이션을 구축하는 경우에는 이 방법으로 컨트롤러를 구현하는것을 권장하지
않는다고 한다.
@Component("/")
public class WelcomeHomeController extends AbstractController {
@Override
protected ModelAndView handleRequestInternal(
HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mav = new ModelAndView("home");
mav.addObject("now", new Date());
return mav;
}
}
HandlerMapping
HandlerMapping 인터페이스는 요청에 대응할 핸들러를 선택하는 역할을 수행한다.
Spring MVC는 비슷한 기능을 하는 다양한 종류의 구현 클래스를 제공하는데 그 중에서도 현대적인 개발 방법으로
사용되는 구현 클래스는 RequestMappingHandlerMapping이다.
RequestMappingHandlerMapping클래스는 @RequestMapping에 정의된 설정 정보를 바탕으로 실행할 핸들러를
선택한다. 예를 들어 다음과 같은 컨트롤러 클래스에서는 hello 메서드와 goodbye메서드가 핸들러로 인식된다.
@Controller
public class GreetingController {
@RequestMapping("/hello")
public String hello() {
return "hello";
}
@RequestMapping("/gooodbye")
public String goodbye() {
return "goodbye";
}
}
핸들러로 인식된 메서드(hello 와 goodbye메서드)는 다음과 같이 @Requestmapping에 지정된 요청 매핑 정보와
매핑된다.
이렇게 /hello라는 요청이 들어오면 요청 매핑정보에서 /hello를 찾아 해당 핸들러를 선택하게 된다.
실제로 클라이언트에서 요청이 올 경우 RequestMappingHandlerMapping 클래스는 요청내용(요청 경로나
HTTP 메서드 등)과 요청 매핑 정보를 매칭해서 실행할 핸들러를 선택한다.
HandlerAdaptor
핸들러 메서드를 호출하는 역할을 한다. Spring MVC는 비슷한 기능을 하는 다양한 종류의 구현 클래스를 제공하지만
ReqeustMappingHandlerMapping 클래스에 의해 선택된 핸들러 메서드를 호출할 때는
ReqeustMappingHandlerAdaptor 클래스를 사용한다.
RequestMappingHanlderAdaptor 클래스에는 핸들러 메서드에 매개변수를 전달하고 메서드의 처리 결과를
반환값으로 되돌려 보내는 것과 같은 Spring MVC에서 상당히 중요한 기능을 수행한다.
핸들러 메서드에 매개변수를 전달할 때는 요청받은 데이터를 자바 객체로 변환하고, 입력값이 올바른지
검사(Bean Validation)하는 것까지 한번에 이뤄진다.
인수나 반환값에 지정할 수 있는 타입으로는 다양한 타입이 기본적으로 지원되지만 상황에따라 기본적으로 지원되지
않는 타입을 지원해야 할 수도 있다.
이러한 상황에 대응하기 위해 Spring MVC는 핸들러 메서드 시그니처를 유연하게 정의할 수 있도록 다음과 같은
인터페이스를 제공한다.
인터페이스명 |
역할 |
HandlerMethodArgumentResolver |
핸들러 메서드 매개변수에 전달하는 값을 다르기 위한 인터페이스 |
HandlerMethodReturnValueHandler |
핸들러 메서드에서 반환된 값을 처리하기 위한 인터페이스 |
ViewResolver
핸들러에서 반환한 뷰 이름을 보고 이후에 사용할 View 인터페이스의 구현 클래스를 선택하는 역할을 한다.
Spring MVC는 viewResolver의 다양한 구현 클래스를 제공하는데 주요 구현 클래스는 아래와 같다.
클래스명 |
설명 |
InternalResourceViewResolver |
뷰가 JSP일 때 사용하며, 가장 기본적인 ViewResolver다. |
BeanNameViewResolver |
DI 컨테이너에 등록된 빈의 형태로 뷰 객체를 가져올 때 사용한다. |
View
클라이언트에 반환하는 응답데이터를 생성하는 역할을 한다. Spring MVC는 다양한 구현 클래스를 제공하는데
주요 클래스는 아래와 같다.
클래스명 |
설명 |
InternalResourceView |
템플릿 엔진을로 JSP를 이용할 때 사용하는 클래스 |
JstlView |
템플릿 엔진으로 JSP + JSTL을 이용할 때 사용하는 클래스 |
레퍼런스
스프링 철저 입문
'Spring' 카테고리의 다른 글
AOP(Aspect Oriented Programming) (0) | 2021.02.20 |
---|---|
의존성 주입(Dependency Injection, DI) (0) | 2021.02.18 |
Spring MVC (0) | 2021.02.16 |
Spring과 SpringBoot 의 차이 (0) | 2021.02.15 |
mybatis null값처리. (0) | 2020.10.29 |