진짜 개발자
본문 바로가기

FrameWork/Spring

Spring - Spring MVC 동작과정 -5

728x90
Spring MVC 분석

SpringMVC에서 Controller는 어떻게 View를 찾을 수 있을 까요?

Spring MVC 프로젝트를 생성하면 자동으로 Controller Class가 생성됩니다. 또한 @RequestMapping어노테이션에 적힌 url로 요청하면 해당 어노테이션이 부여된 메소드가 호출되면서 return에 적힌 jsp페이지를 자동으로 사용자에게 응답하게 됩니다. 어떻게 Controllerreturn에 적힌 String만을 가지고 적절한 jsp(View)를 찾을 까요? 어떻게 가능한지는 먼저 SpringMVC의 동작과정을 알아보면 쉽게 알 수 있을것 같습니다.

 

 

Spring MVC의 동작과정

SpringMVC에서는 최초로 사용자로부터 요청을 전달받게되면 DispatcherServlet이 수신하게 됩니다. 이것을 확인하기 위해 우선 web.xml파일을 열어보겠습니다.

 

1. DispatcherServlet

위의 그림에서 볼 수 있듯이 Spring MVC 프로젝트 생성 후 web.xml(배포서술자)를 읽어보면 우선 /로 시작한다면 즉, 모든요청이 appServlet으로 매핑되는 것을 볼 수 있는데, appServlet이 바로 DispathcherServlet입니다. 이 때문에 사용자의 모든 요청이 DispatcherServlet을 통하게 되는 것입니다.

 

또한 appServlet을 자세히 보면 init-param(초기화 파라미터)의 값으로 /WEB-INF/spring/appServlet/ servlet-context.xml을 가지고 생성되는 것을 볼 수 있습니다.

 

/WEB-INF/spring/appServlet/servlet-context.xml

DispatcherServlet이 생성되면서 초기화 파라미터로 가지는 xml파일을 열어보게 되면 다음과 같습니다. InternalResourceViewResolver를 빈으로 가지게 되는데 사용자에게 보여줄 view를 찾기 위한 prefix, suffix를 제공합니다. 예로들면 controller에서는 home을 return하게 되는데 prefix인 /WEB-INF/views/home 그리고 suffix인 .jsp를 합쳐 /WEB-INF/views/하위에 존재하는 home.jsp를 찾아 사용자에게 보여주게 됩니다.

 

*ViewResolver

ViewResolver는 사용자에게 결과를 렌더링하여 보여주는 역할을 합니다. UrlBasedViewResolver를 상속받았고 거의 역할이 동일합니다. 사용자에게 보여줄 view를 생성할 때 prefix, suffix를 지정하여 view이름과 결합해 해당 경로에있는 view를 찾게 됩니다.

https://isstory83.tistory.com/117 SpringMVC의 ViewResolver에 대해 잘 설명되어있는 블로그입니다.

 

404 ERROR

앞서 설명드린 과정으로 Spring MVC가 동작하기 때문에 위 그림과 같이 jsp 페이지를 직접 실행하는 경우에는 404 ERROR가 나타나게 됩니다. 따라서 프로젝트를 실행하거나 웹브라우저를 통해 서버에 요청해야 합니다.

 

 

2. Controller

DispatcherServlet은 사용자의 요청을 최초로 전달 받은 후 Controller로 전달합니다. 그렇다면 어떤 Controller로 어떻게 알고 요청을 전달을 하게 될까요?

 

/WEB-INF/spring/appServlet/servlet-context.xml

다시 DispatcherServlet이 초기값으로 가지는 설정파일입니다. 하단에 보시면 <context:component-sca base-package="패키지경로"/>가 적혀있는 것을 보실 수 있습니다. 바로 어노테이션을 이용해 Bean을 등록할때 사용했던 태그입니다. component-scan은 @Component 어노테이션 뿐만아니라 Streotype(@Controller, @Service, @Repository)등을 자동으로 스캔하여 Bean으로 등록해주는 태그입니다. 이 덕분에 HomeController 상단의 @Controller 어노테이션을 보고 Bean으로 등록한 후 Controller에게 요청을 전달할 수 있었던것 입니다.

 

사용자의 요청을 전달받은 DispatcherServlet은 위에서 알아본 <context:component-scan/> 태그안의 base-package를 뒤져가며 @Controller이 부여된 Class를 찾습니다. HomeController클래스에 있군요 여기서 @RequestMapping() 의 value를 보고 사용자가 요청한 url에 대응이 되면 해당 메소드가 실행이 됩니다. 여기서 인자로 전달받은 modeladdAttribute("key", "value");메소드를 이용해 view에 값을 전달할 수 있습니다. 그리고 return에 적혀있는 view를 사용자에게 응답하게됩니다.


추가적으로 @Controller에서 @RequestMapping 어노테이션을 보고 요청을 전달하기 위해서는 /WEB-INF/spring/appServlet/servlet-context.xml에 기술된 <annotation-driven />에 대해 알아야 합니다. 다음 블로그에 설명이 잘 되어있습니다. https://gmlwjd9405.github.io/2018/12/18/spring-annotation-enable.html


  

요약

  1. 사용자의 모든 요청을 DispatcherServlet이 전달받습니다
  2. DistpatcherServlet은 web.xml(배포서술자)에 작성된 내용을 기반으로 /WEB-INF/spring/appServlet/servlet-context.xml을 초기 파라미터로 전달받습니다.
  3. /WEB-INF/spring/appServlet/servlet-context.xml에는 Bean으로 자동으로 등록하기 위한 component-scan과 대상이 되는 패키지 경로가 적혀있습니다. 또한 사용자에게 응답할 view를 찾기 위한 viewResolver에 대한 설정도 담겨 있습니다.
  4. 웹 컨테이너는 component-scan의 대상이 되는 패키지안의 Bean으로 등록되기 위한 @(어노테이션)을 가지고 있는 모든 클래스를 Bean으로 등록합니다.
  5. 그 중 사용자가 요청한 url에 대한 처리를 맞고 있는 @Controller클래스에 사용자의 요청을 전달합니다
  6. @Controller가 부여된 클래스안에서 사용자가 요청한 url에 대응되는 @RequestMapping(value="")어노테이션을 가지고 있는 Method가 실행됩니다. 최종적으로 해당 메소드에서 return 하는 String에 대응되는 view를 사용자에게 응답하게 됩니다. (return 하는 String에 대응하는 view를 찾기 위해서는 /WEB-INF/spring/appServlet/servlet-context.xml에 명시된 InternalResourceViewResolverBean의 prefix와 suffix를 합쳐서 view를 찾습니다.)

 

너무 대충 요약한 감이 있는데 꼭 다음 포스팅에서 조금 더 세부적인 내용을 다루도록 하겠습니다. 감사합니다~