참고 자료 : 초보 개발자를 위한 스프링5 프로그래밍 입문
<Chapter 10. 스프링 MVC 프레임워크 동작 방식>
1. 스프링 MVC 핵심 구성 요소
DispatcherServlet은 모든 연결을 담당함
1) 웹 브라우저로부터 요청이 들어옴
2) DispatcherServlet은
해당 요청을 처리하기 위한 컨트롤러 객체를 검색함
(직접 조회하는 것이 아니라 HandlerMapping이라는
빈 객체에게 컨트롤러 검색을 요청함)
3) HandlerMapping은 클라이언트의 요청 경로를 이용하여
이를 처리할 컨트롤러 빈 객체를 DispatcherServlet에 전달
4) HandlerAdapter 빈에게 요청 처리를 위임한다.
5) HandlerAdapter는 컨트롤러의 알맞은 메서드를 호출해 요청을 처리하고 결과를
DispatcherServlet에 리턴한다.
(이때, 컨트롤러의 처리 결과를 ModelAndView라는 객체로 변환하여 전달함)
6) 결과를 보여줄 뷰를 찾기 위해 ViewResolver 빈 객체를 사용함
(매번 새로운 View 객체를 생성해서 DispatcherServlet에게 리턴함)
7) DispatcherServlet은 ViewResolver가 리턴한 View 객체에게
응답 결과 생성을 요청함
1) 컨트롤러와 핸들러
: 클라이언트의 요청을 실제로 처리하는 것은 컨트롤러
DispatcherServlet은 클라이언트의 요청을 전달받는 창구 역할
스프링 MVC는 웹 요청을 실제로 처리하는 객체를
핸들러(Handler)라고 표현하고 있으며
@Controller 어노테이션 적용 객체나
Controller 인터페이스를 구현한 객체는 모두 핸들러에 속한다.
2) DispatcherServlet과 스프링 컨테이너
: DispatcherServle은 스프링 컨테이너를 생성하고
그 컨테이너로부터 필요한 빈 객체를 구한다
3) @Controller를 위한 HandlerMapping과 HandlerAdapter
- HandlerMapping : 웹 브라우저의 요청을 처리할 핸들러 객체를 찾기 위해 사용
- HandlerAdapter : 핸들러를 실행하기 위해 사용
핸들러에 알맞은 HandlerMapping 빈과 HandlerAdapter 빈이
스프링 설정에 등록이 되어 있어야 한다.
- RequestMappingHandlerMapping
: @Controller 어노테이션이 적용된 객체의 요청 매핑 어노테이션(@GetMapping)값을 이용하여
웹 브라우저의 요청을 처리할 컨트롤러 빈을 찾는다
- RequestMappingHandlerAdapter
: 컨트롤러의 메서드를 알맞게 실행하고
그 결과를 ModelAndView 객체로 변환해서
DispatcherServlet에 리턴한다.
@Controller
public class HelloController {
@GetMapping("/hello") // 메서드가 처리할 요청 경로를 지정함
public String hello(Model model, @RequestParam(value="name",required=false) String name) {
model.addAttribute("greeting","안녕하세요" + name);
return "hello";
}
}
RequestMappingHandlerMapping
> "/hello" 요청 경로에 대해 hello() 메서드를 호출함
model 객체를 생성하여 첫 번째 파라미터로 전달하고
name인 HTTP 요청 파라미터의 값을 두 번째 파라미터로 전달함
RequestMappingHandlerAdapter
> 컨트롤러 메서드 결과값이 String이면
해당 값을 뷰 이름으로 갖는 ModelAndVIew 객체를 생성하여
DispatcherServlet에 리턴한다.
4) WebMvcConfigurer
> @EnableWebMvc 어노테이션을 사용하면
@Controller 어노테이션을 붙인 컨트롤러를 위한 설정을 생성함
package config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/WEB-INF/view/", ".jsp");
}
}
> WebMvcConfigurer 타입의 빈 : MvcConfig 클래스
EnableWebMvc 어노테이션을 사용하면
WebMvcConfigurer 타입의 빈 객체의 메서드를 호출해서
MVC 설정을 추가함
5) JSP를 위한 ViewResolver
package config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/WEB-INF/view/", ".jsp");
}
}
컨트롤러의 실행 결과를 받은 DispatcherServlet은
ViewResolver에게 뷰 이름에 해당하는 View 객체를 요청함
6) 디폴트 핸들러와 HandlerMapping의 우선순위
매핑 경로가 "/"인 경우
jsp로 끝나는 요청을 제외한 모든 요청을 DispatcherServlet이 처리
/index.html이나 /css/bootstrap.css와 같이 확장자가 .jsp가 아닌 모든 요청을
DispatcherServlet이 처리함
그런데 @EnableWebMvc가 등록하는 HandlerMapping은
@Controller가 적용한 빈 객체가 처리할 수 있는 요청 경로만 대응 가능함
즉, 그 컨트롤러에서 @GetMapping("/hello")만 설정한다면
"/hello"이외의 다른 경로를 처리할 수 없게 되고
404 error를 내게 됩니다.
이를 처리하기 위해 WebMvcConfigurer의 configureDefaultServletHandling 메소드를 사용함
웹 브라우저에서 요청이 들어오면
DispatcherServlet은
1. RequestMappingHandlerMapping를 사용해서
요청을 처리할 핸들러를 검색함
> 존재하면 해당 컨트롤러를 이용하여 요청 처리함
2. 존재하지 않으면 SimpleUrlHandlerMapping을 사용해서
요청을 처리할 핸들러를 검색함.
-> DefaultServletHandlerConfigurer#enable() 메소드가 등록한
SimpleUrlHandlerMapping을 이용해 모든 경로 ("/**")에 대해
DefaultServletHttpRequestHandler를 리턴
-> DispatcherServlet은 DefaultServletHttpRequestHandler에 처리를 요청
-> DefaultServletHttpRequestHandler는 디폴트 서블릿에 처리를 위임
'여니의 프로그래밍 study > Spring & Spring Boot' 카테고리의 다른 글
[Spring] MVC 2 : 메시지, 커맨드 객체 검증 (1) | 2023.12.08 |
---|---|
[Spring] MVC 1 : 요청 매핑, 커맨드 객체, 리다이렉트, 폼 태그, 모델 (Chapter 11) (0) | 2023.12.02 |
[Spring] 스프링 mvc 시작하기 (Chapter 9) (0) | 2023.11.23 |
[Spring] DB 연동 - 2 (Chapter 8) (1) | 2023.10.08 |
[Spring] DB 연동 - 1(Chapter 8) (1) | 2023.09.16 |