โ™ป๏ธ

์Šคํ”„๋ง MVC ์˜ Request Flow

 
์š” ๊ทธ๋ฆผ์ด ์•„์ฃผ ์ข‹๋‹ค!
์š” ๊ทธ๋ฆผ์ด ์•„์ฃผ ์ข‹๋‹ค!
 
Spring MVC Request Lifecycle์˜ ๊ตฌ์กฐ
ํ•ธ๋“ค๋Ÿฌ ์ธํ„ฐ์…‰ํ„ฐ์˜ ์œ„์น˜๊ฐ€ ์ž˜๋ชป๋จ
ํ•ธ๋“ค๋Ÿฌ ์ธํ„ฐ์…‰ํ„ฐ์˜ ์œ„์น˜๊ฐ€ ์ž˜๋ชป๋จ
 
Servlet Filter
  • โ‘  ์›น๋ธŒ๋ผ์šฐ์ €/ API Client์—๊ฒŒ ์š”์ฒญ์„ ๋ฐ›์Œ
  • โ‘ช ์‘๋‹ต์„ ์›น๋ธŒ๋ผ์šฐ์ €/ API Client์—๊ฒŒ ์ „๋‹ฌํ•จ
 
DispatchServlet
  • โ‘ก ์š”์ฒญ์„ ๋ฐ›์•„ ์•„๋ž˜์˜ ์ฒ˜๋ฆฌ๋ฅผ ํ•จ
    • โ‘ขHandlerMapping์„ ํ†ตํ•ด ์š”์ฒญ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ Controller ํด๋ž˜์Šค๋ฅผ ์ฐพ์Œ
    • โ‘ฃHandlerInterceptor์—๊ฒŒ ์š”์ฒญ ์ •๋ณด์™€ Handler ์ •๋ณด๋ฅผ ํ•จ๊ป˜ ์ „๋‹ฌํ•จ (postHandle)
      • + Argument Resolver ์ฒ˜๋ฆฌ
      • + Message Converter ์ฒ˜๋ฆฌ
    • โ‘จViewResolver์—๊ฒŒ view resolving์„ ์œ„์ž„ํ•จ
    • โ‘ฉ Filter์—๊ฒŒ ์‘๋‹ต
 
 
 
HandlerInterceptor
  • โ‘ค ์š”์ฒญ์— ๋Œ€ํ•œ ์ถ”๊ฐ€์ ์ธ ์ฒ˜๋ฆฌ๋ฅผ ์ง„ํ–‰ํ•˜์—ฌ DispatcherServlet์—๊ฒŒ ๋ฐ˜ํ™˜ํ•จ (preHandle)
  • โ‘ง ์‘๋‹ต์— ๋Œ€ํ•œ ์ถ”๊ฐ€์ ์ธ ์ฒ˜๋ฆฌ๋ฅผ ์ง„ํ–‰ํ•˜์—ฌ DispatcherServlet์—๊ฒŒ ๋ฐ˜ํ™˜ํ•จ (postHandle)
  • 9.5 ๋ทฐ ๋ฆฌ์กธ๋น™ ์ดํ›„์— ์ถ”๊ฐ€์ ์ธ ์ฒ˜๋ฆฌ๋ฅผ ์ง„ํ–‰ํ•˜์—ฌ DispatcherServlet ์—๊ฒŒ ๋ฐ˜ํ™˜ํ•จ (afterCompletion)
 
Controller
  • โ‘ฅ Service Layer์— ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„ํ•จ
  • โ‘ฆ HandlerInterceptor ์— view์˜ path ํ˜น์€ Data๋ฅผ ๋ฐ˜ํ™˜ํ•จ

DispatcherServlet.doDispatch ๋ฉ”์†Œ๋“œ

  • DispatcherServlet๋„ ํ•˜๋‚˜์˜ Servlet์ด๋‹ค.
    • ๋ถ€๋ชจ Servlet์ธ FrameworkServlet์˜ service ๋ฉ”์†Œ๋“œ๋ฅผ ์‹œ์ž‘์œผ๋กœ ์—ฌ๋Ÿฌ ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
    • DispatcherServlet.doDispatch ์š” ๋ฉ”์†Œ๋“œ๊ฐ€ ๊ฐ€์žฅ ์ค‘์š”ํ•˜๋‹ค.
 
 
  • ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ์ƒ๋žต, ์ฃผ์š”ํ•œ ๊ณผ์ •์œ„์ฃผ๋กœ ์ •๋ฆฌ
  • localhost:8080 ๋ฅผ ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ํ˜ธ์ถœํ•œ ์ƒํ™ฉ์„ ๊ฐ€์ •

โ‘ข ํ•ธ๋“ค๋Ÿฌ ๋งคํ•‘ ๊ณผ์ • + ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ ์ฐพ๊ธฐ

โ‘ข - 1 mappedHandler = this.getHandler(processedRequest);
๐Ÿ”ป
@Nullable protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { if (this.handlerMappings != null) { Iterator var2 = this.handlerMappings.iterator(); while(var2.hasNext()) { HandlerMapping mapping = (HandlerMapping)var2.next(); HandlerExecutionChain handler = mapping.getHandler(request); if (handler != null) { return handler; } } } return null; }
ํ•„๋“œ์— ์ •์˜๋œ List<HandlerMapping> handlerMapping๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ
notion image
์š”์ฒญ ์ •๋ณด๋ฅผ ํ†ตํ•ด ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ฐพ์Œ
WelcomPagehandlerMapping์—์„œ ParameterizableViewController ๋ผ๋Š” ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์ฐพ์•„์ง
 
โ‘ข - 2 HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
๐Ÿ”ป
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { if (this.handlerAdapters != null) { Iterator var2 = this.handlerAdapters.iterator(); while(var2.hasNext()) { HandlerAdapter adapter = (HandlerAdapter)var2.next(); if (adapter.supports(handler)) { return adapter; } } } throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler"); }
๋น„์Šทํ•˜๊ฒŒ handlerAdapters๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ํ•ธ๋“ค๋Ÿฌ ์–ด๋Œ‘ํ„ฐ๋ฅผ ์ฐพ์Œ
notion image
ParameterizableViewController๋ฅผ supportํ•˜๋Š” ์–ด๋Œ‘ํ„ฐ์ธ SimpleControllerhandlerAdapter๊ฐ€ ์„ ํƒ๋จ ํ•ด๋‹น ์–ด๋Œ‘ํ„ฐ๋Š” ๊ฐ„๋‹จํ•˜๊ณ„ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ Controller์˜ ์ธ์Šคํ„ด์Šค๋ผ๋ฉด supportํ•จ
public class SimpleControllerHandlerAdapter implements HandlerAdapter { ... public boolean supports(Object handler) { return handler instanceof Controller; } }

๋‹ค์Œ์—๋Š”
mappedHandler.applyPreHandle(processedRequest, response)
HandlerInterceptor์˜ preHandle ํ˜ธ์ถœ

์–ด๋Œ‘ํ„ฐ๋ฅผ ํ†ตํ•œ ํ•ธ๋“ค๋Ÿฌ ํ˜ธ์ถœ
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
ModelAndView ๊ฒฐ๊ณผ๊ฐ’
notion image

๋‹ค์Œ์—๋Š”
mappedHandler.applyPostHandle(processedRequest, response, mv);
HandlerInterceptor์˜ postHandleํ˜ธ์ถœ

๋งˆ์ง€๋ง‰์œผ๋กœ ๋ทฐ ๋ฆฌ์กธ๋น™
this.processDispatchResult(... )
๐Ÿ”ป
this.render(mv, request, response)
๐Ÿ”ป
view = this.resolveViewName( ... )

๋˜ ๋งˆ์ง€๋ง‰์œผ๋กœ
 
HandlerInterceptor์˜ afterCompletion ํ˜ธ์ถœ
 

 
Filter, Interceptor & AOP
์ธํ„ฐ์…‰ํ„ฐ์˜ ์œ„์น˜๊ฐ€ ์ž˜๋ชป๋จ
์ธํ„ฐ์…‰ํ„ฐ์˜ ์œ„์น˜๊ฐ€ ์ž˜๋ชป๋จ
 
์›น๊ณผ ๊ด€๋ จ๋œ ๊ณตํ†ต๊ด€์‹ฌ์‚ฌ - ์„œ๋ธ”๋ฆฟ ํ•„ํ„ฐ, ์ธํ„ฐ์…‰ํ„ฐ
 
AOP๋Š” Interceptor ๋ณด๋‹ค ๋” ์•ˆ์ชฝ์—์„œ ๋™์  ํ”„๋ก์‹œ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์š”์ฒญ ๋ฐ ์‘๋‹ต์— ๋Œ€ํ•œ ์ ‘๊ทผ์ œ์–ด ๋ฐ ๊ธฐ๋Šฅ์ถ”๊ฐ€๋ฅผ ๋‹ด๋‹นํ•จ
 
notion image
 
@) ์ฐธ๊ณ 
damiano1027 - [Spring] Spring MVC Request Lifecycle - ๊ทธ๋ฆผ์ด ์ด์ƒํ•จ