WAS(톰캣)가 Web.xml 파일을 통해서 서블릿을 찾듯이
DispatcherServlet도 /WEB-INF/”서블릿이름”-servlet.xml 파일을 통해서
파일에 설정된 친구들과 함께 요청을 처리하게 된다.
우선 톰캣이 서블릿을 찾고, DispatcherServlet한테 처리해달라고 하면
DispatcherServlet은 이러쿵저러쿵 잘 해서 사용자한테 응답화면을 보여준다는건데...
과연 이게 어떻게 이루어질까? 궁금해졌다.
▶ /WEB-INF/”서블릿이름”-servlet.xml 파일
서블릿이 가지고있는 설정 파일이다. "서블릿이름"부분은 Web.xml에 작성해주면 된다.
<context:component-scan base-package="com.study" />
<mvc:annotation-driven />
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" vlaue="/WEB-INF/views/" />
<beans:property name="suffix" vlaue=".jsp" />
<beans:bean>
▶Controller
스프링이 지원해주는 혜택을 받기위해서는 내가 만든 클래스들을 Bean으로 등록해야한다.
빈은 빈태그를 사용해서 등록해주면 되는데 우리가 만들 클래스는 굉장히 많기 때문에
스프링에서 제공하는 태그가 있다.
<context:component-scan base-package="com.study" />
base-package의 패키지 이름을 넣고, 클래스에는 @Controller, @Service, @Repository같은 특정 어노테이션을 붙여놓으면 해당 패키지를 가진 클래스들을 스캔하면서 빈을 만든다.
package com.sutdy;
import org.springframework.stereotype.Controller;
@Controller
public class MyController {
@GetMapping("/hone")
public String a() {
return "index";
}
}
이렇게 패키지명에 com.study라고 넣게 되면
패키지명이 com.study인 @Controller 어노테이션이 붙어있는 MyController의 빈이 저절로 만들어진다는 것이다.
이렇게 Bean을 만들어준다.
▶ HadnlerMapping과 HandlerAdapter
어노테이션기반의 컨트롤러를 잘 작동하게끔 해주려면
/WEB-INF/”서블릿이름”-servlet.xml 파일 안에
<mvc:annotation-driven />
태그를 작성해줘야한다.
그러면 여러개의 핸들러매핑과 여러개의 핸들러어댑터 종류 중에서
RequsetMappingHadnlerMapping과
RequestMappingHandlerAdapter
이 두가지가 요청처리에 같이 합류하게 된다.
아주 예전 버전의 스프링은 하나의 요청 당 하나의 컨트롤러가 필요했었다.
하지만 지금의 스프링은 하나의 컨트롤러에서 여러 요청을 메소드단위로 처리할 수 있게 되었고
메소드 형태도 내 맘대로 할 수 있도록 자유로워졌다.
그 이유는 바로 RequsetMappingHadnlerMapping과 RequestMappingHandlerAdapter 클래스 덕분이다.
과연 이 클래스들이 어떤 역할을 해줄까?
▷ RequsetMappingHadnlerMapping
RequsetMappingHadnlerMapping은 Controller 클래스의 메소드를 돌아다니면서 아래와 같은 정보를 수집해온다.
"{[/new],methods=[GET]}"
public String com.study.MyController.creat()
위에 부분이 주소하고 어떤 메소드인지가 적혀져있는 key값이고
아래 부분이 실제로 요청이 들어왔을 때 실행되는 Controller의 메소드인 value값이다.
즉, DispatcherServlet이 RequestMappingHandlerMapping한테
"요청처리 어디서함??" 이라고 물어보면
RequestMappingHandlerMapping은 수집해온 정보들을 넘겨주면서
"/new에서 하면되고, method는 GET임"
이렇게 바로 대답해 줄 수 있는 것이다.
▷ RequestMappingHandlerAdapter
이렇게 받은 정보를 가지고 DispatcherServlet은 RequestMappingHandlerAdapter한테 간다.
잠시 컨트롤러로 가서 보면
처리할 메소드의 형태를 보면 다 다르다.
매개변수의 개수와 타입, return형도 다 다르게 할 수 있다.
이렇게 형태의 메소드들을
RequestMappingHandlerAdapter가 필요한 매개변수값들을 척척 채워주면서 메소드가 적절히 잘 실행되도록 해준다.
이렇게 잘 실행되게 해주고 난 후 RequestMappingHandlerAdapter는 DispatcherServlet한테
ModelAndView객체를 return해준다.
▶ ModelAndView
요청처리하는 코드가 다 실행이 되고나면 사용자에게 제공 될 정보가 만들어진다.
이렇게 사용자에게 제공 될 정보를 Model이라고 한다.
View는 응답화면을 뜻한다.
정확히 말하면 응답화면을 찾는 힌트값이다.
이 힌트값은 요청처리를 한 return값이다.
정리를하면
ModelAndView = 사용자에게 제공 될 정보 + 화면 찾는 힌트값
이다.
RequestMappingHandlerAdapter는 DispatcherServlet한테
사용자에게 제공 될 정보 + 화면 찾는 힌트값을 return해 준 것이다.
▶ ViewResolver
마지막으로 볼건 ViewResolver이다.
ViewResolver는 실행할 뷰를 찾는 일을한다.
ViewResolver의 종류는 2가지가 있다.
- ResourceBundleViewResolver
- *.properties 에서 뷰 이름에 해당하는 컴포넌트의 URL을 찾는다.
2. InternalResourceViewResolve
- 미리 지정된 접두사, 접미사를 사용하여 뷰이름으로 컴포넌트의 URL을 완성해 URL을 지정하기 편리하다.
- 교체 방법은 XML에서 설정하는 방법과 Java Config로 설정하는 방법이 있다.
우리는 InternalResourceViewResolve방식을 사용했다.
<context:component-scan base-package="com.study" />
//Controller
<mvc:annotation-driven />
//RequsetMappingHadnlerMapping과 RequestMappingHandlerAdapter
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" vlaue="/WEB-INF/views/" />
<beans:property name="suffix" vlaue=".jsp" />
<beans:bean>
//InternalResourceViewResolver
이렇게 InternalResourceViewResolver는
실제로 응답 할 화면의
경로(URL)와 파일 이름을 제공한다.
바로 위 코드에서 prefix와 suffix의 value값을 이용해서 제공하는데
RequestMappingHandlerAdapter가 준 힌트값을
prefix값 + 힌트 값 + suffix값
이렇게 중간에 넣어주면 된다.
예시로 이걸 보자면
힌트값(URL)은 return값인 login인이 될 것이고,
prefix의 value는 /WEB-INF/views/
suffix의 value는 .jsp이므로
/WEB-INF/views/login.jsp 이 된다.
ViewResolver는 이 뷰 이름에 해당하는 View 객체를 찾거나 생성해 반환한다.
그 후 DispatcherServlet은 ViewResolver가 반환한 View 객체에게 응답 결과 생성을 요청한다.
▣Reference.
https://youtu.be/GRxfNQe0_bI?si=w7Q3yTfvzfsje66U
'BackEnd > Spring Boot🍃' 카테고리의 다른 글
[Spring] 의존성주입(DI)이란? 의존성주입의 4가지 방법 (0) | 2024.04.07 |
---|---|
[Spring] ApplicationContext란? ApplicationContext Interface를 구현하고 있는 대표적인 클래스들, Bean 등록 방식 (0) | 2024.04.06 |
[Spring] Servlet과 Spring Web MVC(2) (0) | 2024.03.23 |
[Spring] Servlet과 Spring Web MVC(1) (0) | 2024.03.23 |
[Spring Boot] 스프링부트 개념정리 (1) | 2024.02.24 |