๐ DispatcherServlet
์๋ ํ์ธ์, ์ด๋ฒ ํฌ์คํ ์์๋ Spring์์ HTTP ์์ฒญ ๋ฐ ์๋ต๊ณผ ๊ด๋ จํ์ฌ ๊ฐ์ฅ ํต์ฌ ๊ธฐ์ ์ธ DispatcherServlet์ ๋ํด ์ดํด๋ณด๊ณ ์ ํฉ๋๋ค.
ํ์์ ๊ฐ๋ ์ ๋ํด์๋ ์ด๋ ์ ๋ ์๊ณ ์์์ง๋ง ์ด๋ ํ ๊ณผ์ ์ ํตํด ๋์คํจ์ฒ ์๋ธ๋ฆฟ์ด ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ๋ฐ๊ณ , ๋ฉ์๋์ ํ๋ผ๋ฏธํฐ ์ ๋ณด๋ฅผ ์ฒ๋ฆฌํ๊ณ ์๋ต์ ๋ฐํํ๋์ง ๋ด๋ถ ๋์์ ์ ๋ชฐ๋์๋๋ฐ์, ์ด๋ฒ ๊ธฐํ์ ์ ๋ฆฌํด ๋ณด์์ต๋๋ค.
(ํ๋ฆฐ ๋ด์ฉ์ด ์กด์ฌํ ์ ์์ผ๋ ๋ง์ํด ์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค. ๐)
| DispatcherServlet ๊ฐ๋
ํ๋ก ํธ ์ปจํธ๋กค๋ฌ(Front Controller)๋ผ๊ณ ๋ ๋ถ๋ฆฌ๋ DispatcherServlet์ HTTP ํ๋กํ ์ฝ๋ก ๋ค์ด์ค๋ ๋ชจ๋ ์์ฒญ์ ๋จผ์ ๋ฐ์์ ์ ํฉํ ์ปจํธ๋กค๋ฌ์ ์์(Delegate request)๋ ์ญํ ์ ํฉ๋๋ค.
(์๋์ด๋ฏธ์ง์์ Front controller ๋ถ๋ถ์ DispatcherServlet์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋ฉ๋๋ค.)
| DispatcherServlet ์ฅ์
๊ณผ๊ฑฐ DispatcherServlet์ด ๋ฑ์ฅํ๊ธฐ ์ ์๋ ๋ชจ๋ ์๋ธ๋ฆฟ์ ๋ํด URL์ ๋งคํํ๊ธฐ ์ํด ๊ด๋ จ ์ค์ ์ ํด์ฃผ์ด์ผ ํ๋ ๋ฒ๊ฑฐ๋ก์์ด ์กด์ฌํ์ต๋๋ค. (web.xml ํ์ผ) >> ๋๊ธ ์ฐธ๊ณ ๋ฐ๋๋๋ค. ๐
๊ทธ๋ฌ๋ DispatcherServlet์ด ๋ฑ์ฅํ ์ดํ์๋ DispatcherServlet์ด ๋ชจ๋ ์์ฒญ์ ๋จผ์ ๋ฐ์์ ์ง์ ์ ํฉํ ์ปจํธ๋กค๋ฌ๋ก ์์์ ํด์ฃผ๊ธฐ ๋๋ฌธ์ ์์ ๊ฐ์ ์์ ์ ํ์์์ด์ก๊ณ , ์ด๋ก ์ธํด ๊ฐ๋ฐ์ด ๊ต์ฅํ ํธ๋ฆฌํด์ก์ต๋๋ค.
๊ฐ๋ฐ์์ ์ ์ฅ์์ ๊ต์ฅํ ํธ๋ฆฌํด์ง ๋งํผ DispatcherServlet์ ๋ด๋ถ ์ฝ๋๋ ๊ต~์ฅํ ์ถ์ํ๊ฐ ๋์ด์๊ณ ๋ณต์กํ๋ฐ์, ์ด๋ ํ ๊ณผ์ ์ ๊ฑฐ์ณ ์์ ๊ฐ์ ๋ง๋ฒ(?)์ ๋ถ๋ฆฌ๊ฒ ํด์ฃผ๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค.
| DispatcherServlet ๋์ ๊ณผ์
DispatcherServlet์ ๋์ ๊ณผ์ ์ ๋ํด ์กฐ๊ธ ๋ ์์ธํ ์ดํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- DispatcherServlet์ด ํด๋ผ์ด์ธํธ์ ๋ชจ๋ ์์ฒญ์ ๋ฐ์ต๋๋ค.
- ์์ฒญ ์ ๋ณด์ ๋ํด HandlerMappinng์ ์์ํ์ฌ ์ฒ๋ฆฌํ Handler(Controller)์ ์ฐพ์ต๋๋ค.
- 2๋ฒ์์ ์ฐพ์ Handler์ ์ํํ ์ ์๋ HandlerAdapter๋ฅผ ์ฐพ์ต๋๋ค.
- HandlerAdapter๋ Controller์ ๋น์ฆ๋์ค ๋ก์ง ์ฒ๋ฆฌ๋ฅผ ํธ์ถํฉ๋๋ค.
- Controller๋ ๋น์ฆ๋์ค ๋ก์ง์ ์ํํ๊ณ , ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ Model์ ์ค์ ํ๋ฉฐ HandlerAdapter์ view name์ ๋ฐํํฉ๋๋ค.
- ๋ชจ๋ธ์ ๋ฐํํ๋ฉด View๊ฐ ๋ ๋๋ง์ด ๋๊ณ , ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ(ex. @RestController ๋ฑ) View๊ฐ ๋ ๋๋ง์ด ๋์ง ์์ต๋๋ค.
- 5๋ฒ์์ ๋ฐํ๋ฐ์ view name์ ViewResolver์๊ฒ ์ ๋ฌํ๊ณ , ViewResolver์ ํด๋นํ๋ View ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค.
- DispatcherServlet์ View์๊ฒ Model์ ์ ๋ฌํ๊ณ ํ๋ฉด ํ์๋ฅผ ์์ฒญํฉ๋๋ค.
- ์ต์ข ์ ์ผ๋ก ์๋ฒ์ ์๋ต์ ํด๋ผ์ด์ธํธ์๊ฒ ๋ฐํํฉ๋๋ค.
๐ DispatcherServlet ๋ด๋ถ ์ฝ๋
DispatcherServlet์ ๋ด๋ถ ์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉด Spring ํ์์ ๊ฐ๋ฐํ ์ฌ๋ฌ ๋์์ธ ํจํด์ด ์กด์ฌํฉ๋๋ค.
์๋ ํจํด๋ค์ ์ ๋ถ ์ฝ๋์์ ๋์ค๋ ๊ฐ๋ ๋ค์ด๋ ๊ฐ๋ตํ ์ดํด๋ณด์๊ณ ํด๋น ํฌ์คํ ์ ๋ณด์๋ฉด ์ดํดํ์๊ธฐ์ ๋ณด๋ค ์์ํ ๋ฏ ํฉ๋๋ค. ๐
์ ๊ทธ๋ผ ๊ธธ๊ณ ๋ ๊ธด DispatcherServlet ๋ด๋ถ ์์ผ๋ก์ ์ฌ์ ์ ๋ ๋ ๋ณด๊ฒ ์ต๋๋ค..
DispatcherServrlet์ Spring MVC์ ํต์ฌ ์์๋ก ์ ์ฌ์ง๊ณผ ๊ฐ์ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
(DispatcherServlet -> FrameworkServlet -> HttpServletBean -> HttpServlet -> GenericServlet -> Servlet)
Servlet
- Servlet์ ์น ์๋ฒ ๋ด์์ ์คํ๋๋ ์๋ฐ ํ๋ก๊ทธ๋จ์ ๋๋ค.
- HTTP ํต์ ์ ์ฌ์ฉํ์ฌ ์น ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ์์ฒญ์ ๋ฐ๊ณ ์๋ตํ๋ ๊ธฐ์ ์ ๋๋ค.
- ์ผ๋ฐ์ ์ธ ์๋ธ๋ฆฟ์ ์์ํ๋ GenericServlet, HTTP ์๋ธ๋ฆฟ์ ์์ํ๋ HttpServlet์ด ์กด์ฌํฉ๋๋ค.
- ์๋ธ๋ฆฟ์ ์๋ช ์ฃผ๊ธฐ - init(), service(), destory()
- Servlet์ ๋ํ ์ถ๊ฐ์ ์ธ ๋ด์ฉ์ ํด๋น ํฌ์คํ ์ ์ฐธ๊ณ ํด ์ฃผ์ธ์.
GenericServlet
- ํ๋กํ ์ฝ์ ๋ ๋ฆฝ์ ์ธ ์ผ๋ฐ ์๋ธ๋ฆฟ์ ๋๋ค.
- ์น์์ ์ฌ์ฉํ HTTP ์๋ธ๋ฆฟ์ ์์ฑํ๋ ค๋ฉด HttpServlet์ ์์๋ฐ์ต๋๋ค.
HttpServlet
- ์น ์ฌ์ดํธ์ ์ ํฉํ HTTP ์๋ธ๋ฆฟ ์ ๋๋ค.
- HttpServlet์ ํ์ ํด๋์ค๋ ์๋ ๋ฉ์๋ ์ค ์ต์ ํ๋์ ๋ฉ์๋๋ ์ฌ์ ์๋ฅผ ํด์ผ ํฉ๋๋ค.
- doGet(), doPost(), doPut(), doDelete()
- init(), destory(): ์๋ธ๋ฆฟ ๋ผ์ดํ ์ฌ์ดํด์ ์ด๊ธฐํ ๋ฐ ํ๊ธฐ
- getServletInfo(): ์๋ธ๋ฆฟ์ ๋ํ ์ ๋ณด
HttpServletBean
- HttpServlet์ ๋จ์ ํ์ฅ ํด๋์ค๋ก Spring์ด ๊ตฌํํ ๋ชจ๋ ์๋ธ๋ฆฟ ์ ํ์ ์ ํฉํ ์๋ธ๋ฆฟ (spring ํจํค์ง)
FrameworkServlet
- ์คํ๋ง ์น ํ๋ ์์ํฌ์ ๊ธฐ๋ณธ ์๋ธ๋ฆฟ์ ๋๋ค.
- ํ์ ํด๋์ค๋ ์์ฒญ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด doService() ๋ฉ์๋๋ฅผ ๊ตฌํํด์ผ ํฉ๋๋ค.
- HTTP ์์ฒญ์ ์ฒ๋ฆฌํ๋ ์ค์ ์ง์คํ Dispatcher (Front-Controller)
- ์ ์ ํ ์ด๋ํฐ ํด๋์ค๋ฅผ ํตํด ์ด๋ ํ workflow์๋ ์ฌ์ฉ์ด ๊ฐ๋ฅํ ๋งํผ ๋งค์ฐ ์ ์ฐํฉ๋๋ค.
- Mapping, Adapter, Exception ๊ด๋ จ ํด๋์ค๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- HandlerMapping - RequestMappingHandlerMapping
- HandlerAdapter - RequestMappingHandlerAdapter
- HandlerExceptionResolver - ExceptionHandlerExceptionResolver
์ค์ ๋ก ํด๋ผ์ด์ธํธ์ ์์ฒญ์ DispatcherServlet์ด ๋ฐ์์ ์ฒ๋ฆฌํ๋ ๊ณผ์ ์ ํ๋์ฉ ๋ณด๊ฒ ์ต๋๋ค.
(API ์ ๋ณด, ํด๋์ค ๋ฐ ๋ฉ์๋ ์ ๋ณด, ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ ๋ฑ๋ฑ)
์์ ์ ์ฌ์ฉ๋ ๊ฐ๋จํ API๋ ๋ค์๊ณผ ๊ฐ๊ณ , ํธ์ถ URI๋ '/test?name=juhyun' ์ ๋๋ค.
DispatcherServlet์ด ์์ฒญ์ ๋ฐ์์ ์ฒ๋ฆฌํ๋ ๊ณผ์ ์ ํฌ๊ฒ ์ดํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
1. HttpServlet: ์๋ธ๋ฆฟ์ Request/Response๋ฅผ HttpServlet์ Request/Response๋ก ๋ณํ
2~5. FrameworkServlet: ํด๋ผ์ด์ธํธ ์์ฒญ์ Http Method์ ๋ฐ๋ผ ๋ถ๊ธฐ ์ฒ๋ฆฌ - doXXX ๋ฉ์๋
6. DispatcherServlet: ์์ฒญ ์ ๋ณด์ ๋ํด ์ด๋ฅผ ์ฒ๋ฆฌํ Handler๋ฅผ ์ฐพ๊ณ , HandlerAdapter๋ฅผ ํตํด Controller์ ์์ฒญ ์์
6-1. ์์ฒญ์ ๋งคํ๋๋ HandlerMapping(HandlerExecutionChain) ์กฐํ
6-2. Handler์ ์ํํ ์ ์๋ HandlerAdapter ์กฐํ
6-3. HandlerAdapter๋ฅผ ํตํด ์ค์ Controller์ ๋น์ฆ๋์ค ๋ก์ง ํธ์ถ
1. HttpServlet: Servlet์ Request, Response๋ฅผ HttpServlet์ Request,Response๋ก ๋ณํ
- HttpServlet.service()
๋จผ์ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ DispatcherServlet์ ๋ถ๋ชจ ์ถ์ ํด๋์ค์ธ HttpServlet์ service() ๋ฉ์๋์์ ์์ฒญ์ ๋ฐ์ต๋๋ค.
์ ์ฝ๋์ 13, 14๋ผ์ธ์์ ์๋ธ๋ฆฟ์ ์์ฒญ ๋ฐ ์๋ต์ HttpServlet์ ์์ฒญ ๋ฐ ์๋ต์ผ๋ก ๋ณํํฉ๋๋ค.
์ดํ 18๋ฒ์งธ ๋ผ์ธ์ service() ๋ฉ์๋๋ FrameworkServlet ์ถ์ ํด๋์ค์์ ์ค๋ฒ๋ผ์ด๋๋ service() ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค.
์ req, res๋ Facade ํด๋์ค์ด๋ฉฐ HttpServletRequest, HttpServletResponse ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ธฐ ๋๋ฌธ์ ๋ณํ์ด ๊ฐ๋ฅํฉ๋๋ค.
2. FrameworkServlet: HTTP ๋ฉ์๋์ ๋ฐ๋ผ ๋ถ๊ธฐ ์ฒ๋ฆฌ
- HttpServlet.service() -> FrameworkServlet.service()
Http Method๊ฐ PATCH์ผ ๊ฒฝ์ฐ processRequest() ๋ฉ์๋๋ฅผ ํธ์ถํ๊ณ , ๊ทธ ์ธ์ ๋ฉ์๋๋ 14๋ผ์ธ์ super.service() ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค. (super = HttpServlet)
์๋์์ ์ดํด๋ณด๊ฒ ์ง๋ง doXXX ๋ฉ์๋์์ doPatch() ๋ผ๋ ๋ฉ์๋๋ง ์ ์ผํ๊ฒ ์กด์ฌํ์ง ์๋๋ฐ์, ์ด์ ๋ ๋ค์๊ณผ ๊ฐ๋ค๊ณ ํฉ๋๋ค.
Servlet api 3.0์ ์ ์ํ JSR 315์์ patch ๋ฉ์๋์ ๋ํด ์ธ์ํ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ doPatch() ๋ฉ์๋๋ฅผ ๊ตฌํํ์ง ๋ชปํ๊ณ , ์ดํ PATCH ๋ฉ์๋๊ฐ HTTP ํ๋กํ ์ฝ์ ์ถ๊ฐ๋๋ฉด์ Spring ํจํค์ง์ ์ํ๋ FrameworkServlet ํด๋์ค์์ ๋ถ๊ธฐ ์ฒ๋ฆฌ๋ฅผ ํตํด Http Method๊ฐ PATCH์ธ ์ผ์ด์ค์ ๊ทธ ์ธ์ ์ผ์ด์ค๋ฅผ ๊ตฌ๋ถํ์ฌ ์ฒ๋ฆฌํ๋๋ก ๋์ํ์ต๋๋ค.
- https://stackoverflow.com/questions/47080677/java-httpservlet-patch-method
ํ์ฌ ์์ฒญํ Http Method๋ GET์ด๋ฏ๋ก 14๋ผ์ธ์ super.service() ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ๋ค์ HttpServlet ํด๋์ค์ service() ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค.
3. HttpServlet: service()
- HttpServlet.service() -> FrameworkServlet.service() -> HttpServlet.service()
HttpServlet ์ถ์ ํด๋์ค์ service() ๋ฉ์๋๋ Http Method์ ๋ฐ๋ผ doXXX ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค.
์ค์ ํธ์ถ์ HttpServlet ํด๋์ค๋ฅผ ์์๋ฐ๊ณ , doXXX ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํ๊ณ ์๋ ์์ ํด๋์ค์ doXXX ๋ฉ์๋์ ๋๋ค.
(์ฌ๋ด์ด์ง๋ง ์ lastModified ๊ฐ์ ํญ์ -1์ธ๋ฐ, ๋ฐ๋ก ๋ถ๊ธฐ ์ฒ๋ฆฌ๋ฅผ ํด๋์ ์ด์ ๊ฐ ๊ถ๊ธํ๋ค์.. ๐ง)
HttpServlet ์ถ์ ํด๋์ค์์ ํ ํ๋ฆฟ์ ์ ๊ณตํ๊ณ , ์ค์ ๋น์ฆ๋์ค ๋ก์ง์ ์ด๋ฅผ ์์๋ฐ๋ FrameworkServlet์์ ๊ตฌํ๋์ด ์๋๋ฐ์, ์ด๋ ๋์์ธ ํจํด์์ ํ ํ๋ฆฟ ๋ฉ์๋ ํจํด์ด ์ ์ฉ๋์์์ ํ์ธํ ์ ์์ต๋๋ค.
4. FrameworkServlet: doXXX() -> processRequest() -> doService()
- HttpServlet.service() -> FrameworkServlet.service() -> HttpServlet.service() -> FrameworkServlet.doXXX(), processRequest(), doService()
์์ ํด๋์ค์์ ์ค๋ฒ๋ผ์ด๋ฉ๋ doXXX ๋ฉ์๋๋ ์์ ๊ฐ์ด ๋ชจ๋ processRequest() ๋ฉ์๋๋ฅผ ํธ์ถํ๋๋ก ๋์ด์์ต๋๋ค.
FrameworkServlet ์ถ์ ํด๋์ค์ processRequest() ๋ฉ์๋์์ ํต์ฌ ๋ก์ง์ 7๋ฒ์งธ ๋ผ์ธ์ doService() ์ ๋๋ค.
doService() ๋ฉ์๋๊ฐ ๋๋์ด DispatcherServlet ํด๋์ค๋ฅผ ํธ์ถํ๋ ์ง์ ์ ์ ๋๋ค!
๊ทธ๋ผ DispatcherServlet์ doService() ๋ฉ์๋์์๋ ์ด๋ ํ ๊ณผ์ ์ด ์ผ์ด๋๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค.
5. DispatcherServlet: doService()
- HttpServlet.service() -> FrameworkServlet.service() -> HttpServlet.service() -> FrameworkServlet.doXXX(), processRequest(), doService() -> DispatcherServlet.doService(), doDispatch()
doService() ๋ฉ์๋์์๋ Request์ ๋ํด log๋ฅผ ๋จ๊ธฐ๊ณ , ๋ณต์ํ ์ ์๋๋ก ์์ฒญ ์ ๋ณด์ ๋ํด snapshot์ ๋จ๊ธฐ๋ ๋ฑ ๋ก์ง์ด ์กด์ฌํ์ง๋ง, ํต์ฌ ๋ก์ง์ ์๋๊ธฐ ๋๋ฌธ์ ํจ์คํ๊ฒ ์ต๋๋ค.
ํด๋น ๋ฉ์๋์์ ๊ฐ์ฅ ์ค์ํ ๋ถ๋ถ์ 16๋ฒ์งธ ๋ผ์ธ์ doDispatch() ๋ฉ์๋์ธ๋ฐ์, ์ด ํจ์์์ ์๋์ ์์ ์ ์งํํฉ๋๋ค.
- ์์ฒญ์ ๋งคํ๋๋ HandlerMapping(HandlerExecutionChain) ์กฐํ
- Handler์ ์ํํ ์ ์๋ HandlerAdapter ์กฐํ
- HandlerAdapter๋ฅผ ํตํด Controller ํธ์ถ (์ค์ ๋ก์ง)
DispatcherServlet.doDispatch()
- Process the actual dispatching to the handler.
- The handler will be obtained by applying the servlet's HandlerMappings in order. The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters to find the first that supports the handler class.
- All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers themselves to decide which methods are acceptable.
6. DispatcherServlet: doDispatch() - HandlerMapping, HandlerAdapter, Handle Controller
- HttpServlet.service() -> FrameworkServlet.service() -> HttpServlet.service() -> FrameworkServlet.doXXX(), processRequest(), doService() -> DispatcherServlet.doService(), doDispatch() - HandlerMapping, HandlerAdapter, handle Controller
doDispatch() ๋ฉ์๋๋ ์์์ ๋ง์๋๋ ธ๋ฏ์ด ์ธ ๊ฐ์ง ํต์ฌ ์์ ์ ์งํ ํฉ๋๋ค.
- 18 ๋ผ์ธ: HandlerMapping(HandlerExecutionChain) ์กฐํ
- 26๋ผ์ธ: Handler์ ์ํํ HandlerAdapter ์กฐํ
- 45๋ผ์ธ: HandlerAdapter๋ฅผ ํตํด Controller์ ์ค์ ๋ก์ง ํธ์ถ
6-1. ์์ฒญ์ ๋งคํ๋๋ HandlerMapping(HandlerExecutionChain) ์กฐํ
HandlerExecutionChain์ HandlerMethod, Interceptor๋ค๋ก ๊ตฌ์ฑ๋์ด HandlerMapping์ ํด๋นํ๋ ํด๋์ค ์ ๋๋ค.
HandlerExecutionChain
- Handler execution chain, consisting of handler object and any handler interceptors.
- Returned by HandlerMapping's HandlerMapping.getHandler method.
DispatcherServlet์ด HandlerExecutionChain ๊ฐ์ฒด๋ฅผ ์ป๋ ์ด์ ๋ doDispatch() ๋ฉ์๋์ ๋ฑ๋ก๋
์ธํฐ์ ํฐ๋ฅผ ์ฒ๋ฆฌ ํ๋ ๋ก์ง์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ๋๋ค.(applyPreHandle, applyPostHandle)
์ ์ฝ๋์์ 5๋ฒ ๋ผ์ธ์ mapping.getHandler(request) ๋ฉ์๋๋ฅผ ๋ด๋ถ๋ก ๊ณ์ ๋ค์ด๊ฐ๋ณด๊ฒ ์ต๋๋ค.
(DispatcherServlet.getHandler() -> AbstractHandlerMapping.getHandler() -> RequestMappingInfoHandlerMapping.getHandlerInternal() -> AbstractHandlerMethodMapping.getHandlerInternal())
getHandler() ๋ฉ์๋๋ฅผ ๊ณ์ ํ๊ณ ๋ค์ด๊ฐ๋ณด๋ฉด AbstractHandlerMethodMapping ์ถ์ ํด๋์ค์ getHandlerInternal() ๋ฉ์๋์์ HandlerMethod๋ฅผ ์ฐพ๊ณ , AbstractHandlerMapping ์ถ์ ํด๋์ค์์ HandlerExecutionChain ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ๋ฆฌํดํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
- lookupPath: URI
- mappingRegistry: ๋งคํ ์ ๋ณด๋ฅผ ๊ด๋ฆฌํ๋ ํด๋์ค
- handlerMethod: bean, beanFactory, Controller์ method ์ ๋ณด ๋ฑ
์ด์ ๋น ์ ธ๋์์ AbstractHandlerMapping.getHandler() ๋ถ๋ถ์ ์ดํด ๋ณด๊ฒ ์ต๋๋ค.
getHandlerInternal() ๋ฉ์๋๋ฅผ ์ํํ ํ handler์ ํ์ ์ HandlerMethod ์ด๊ณ , ์ํ๋ ์ ์๋ ์ธํฐ์ ํฐ๋ค์ ํฌํจํ์ฌ getHandlerExecutionChain() ๋ฉ์๋๋ฅผ ํตํด HandlerExecutionChain ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค. (13๋ผ์ธ, 22๋ผ์ธ ~)
์์ ๊ฐ์ ๊ณผ์ ์ ํตํด HandlerMapping์ ์ฐพ๊ณ , HandlerExecutionChain ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ๋ฐํํฉ๋๋ค.
๋ค์์ผ๋ก HandlerExecutionChain์ ํตํด HandlerAdapter๋ฅผ ์ฐพ๋ ๊ณผ์ ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
6-2. Handler์ ์ํํ ์ ์๋ HandlerAdapter ์กฐํ (28๋ฒ์งธ ๋ผ์ธ)
getHandlerAdapter(): HandlerExecutionChain๋ฅผ ํตํด HandlerAdapter๋ฅผ ์ฐพ์ต๋๋ค.
์์ ์ฝ๋์์ ์์ฑํ๋ @GetMapping ์ด๋ ธํ ์ด์ ๋ด๋ถ์ @RequestMapping ์ด๋ ธํ ์ด์ ์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ์์ for๋ฌธ์์๋ RequestMappingHandlerAdapter ์ด๋ํฐ๋ฅผ ๋ฐํํฉ๋๋ค.
(๋ค์ด๋ฐ๋ง ๋ด๋ ํด๋์ค์ ์ญํ ์ด ์ ์ถ๊ฐ ๊ฐ๋ฅํ๋ค์,, Spring ์ญ์ ๋๋จํ๋ค์.. ๐)
๋ํ ์์์ handler์ HandlerMethod๋ก ๋งคํ๋๋ ์ปจํธ๋กค๋ฌ์ ๋ฉ์๋ ๋ฐ ๋น, ๋น ํฉํ ๋ฆฌ ๋ฑ์ด ์ ์ฅ๋์ด ์์ต๋๋ค.
6-3. HandlerAdapter๋ฅผ ํตํด ์ค์ Controller์ ๋น์ฆ๋์ค ๋ก์ง ํธ์ถ (40๋ฒ์งธ ๋ผ์ธ)
6-1, 6-2์์ HandlerExecutionChain, HandlerAdapter๋ฅผ ์ฐพ๋ ๊ณผ์ ์ ์ดํด๋ณด์์ต๋๋ค.
(๋ ๊ณผ์ ๋ ๋ณต์กํ์ง๋ง ์ด๋ฒ 6-3 ๊ณผ์ ์ด ๋ ๋ณต์กํฉ๋๋ค...๐ญ)
๋ง์ง๋ง์ผ๋ก HandlerAdapter๋ฅผ ํตํด ์ค์ Controller์ ๋ก์ง์ ์คํํ๋(invoke) ๊ณผ์ ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
HandlerAdapter๊ฐ Controller๋ฅผ ์คํํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ์ป๋ ๊ณผ์ ์ ๋ง์ด ๋ณต์กํ๊ธฐ ๋๋ฌธ์ ๋ง์ ์ธ๋ด์ฌ(?)์ด ํ์ํฉ๋๋ค... ๐
HandlerAdapter์ handle() ๋ฉ์๋๋ฅผ ํ๊ณ ๋ค์ด๊ฐ ๋ณด๊ฒ ์ต๋๋ค.
RequestMappingHandlerAdapter ํด๋์ค์ handleInternal() ๋ฉ์๋์์ Controller๋ฅผ ํธ์ถํ๋ ๋ก์ง์ด ์กด์ฌํฉ๋๋ค. (invokeHandlerMethod())
๊ทธ๋์ invokeHandlerMethod() ๋ฉ์๋์ ๋ด๋ถ๋ ..?
invokeHandlerMethod ํจ์์์ ์ดํด๋ณผ ๋ถ๋ถ์ ํฌ๊ฒ ๋ ๊ฐ์ง ์ ๋๋ค.
- 10๋ฒ์งธ ๋ผ์ธ: ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(...)
- 23๋ฒ์งธ ๋ผ์ธ: invokeAndHandle(...)
10๋ฒ์งธ ๋ผ์ธ์์ createInvocableHandlerMethod(handlerMethod) ๋ฉ์๋๋ฅผ ํตํด ServletInvocableHandlerMethod ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์์ต๋๋ค.
๊ทธ๋ผ ServletInvocableHandlerMethod ํด๋์ค๋ ๋ฌด์์ผ๊น์??
HandlerMethod๋ฅผ ์์๋ฐ๊ณ ์๋ ํด๋์ค ์ค ํ๋์ ๋๋ค.
ํด๋์ค ์๋จ์ ์ฃผ์์ ์ค๋ช ํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค. (์ค์ญ์ด ์กด์ฌํ ์๋..?)
๋ฑ๋ก๋ HandlerMethodReturnValueHandler๋ฅผ ํตํด ๋ฐํ ๊ฐ์ ์ฒ๋ฆฌํ๋ ๊ธฐ๋ฅ์ผ๋ก InvocableHandlerMethod๋ฅผ ์์๋ฐ๊ณ , ๋ฉ์๋ ๋ ๋ฒจ์์์ @ResponseStatus ์ด๋ ธํ ์ด์ ์ ํตํด ์๋ต ์ํ๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค.
๊ทธ๋ผ InvocableHandlerMethod๋??
HandlerMethodArgumentResolver ๋ฆฌ์คํธ๋ฅผ ํตํด ํ์ฌ HTTP ์์ฒญ์์ ๋ฐ์ ์ธ์ ๊ฐ์ผ๋ก ๊ธฐ๋ณธ ๋ฉ์๋๋ฅผ ํธ์ถ(invoke)ํ๋ HandlerMethod๋ฅผ ์์๋ฐ๋ ํด๋์ค์ ๋๋ค.
์ํ! ์๋ฒฝํ๊ฒ ์ดํด๋ฅผ ํ ๊ฑด ์๋์ง๋ง, ServletInvocableHandlerMethod๋ HandlerMethod์ ํจ๊ป ์ปจํธ๋กค๋ฌ์ ํ๋ผ๋ฏธํฐ(HandlerMethodArgumentResolver) ๋ฐ ๋ฐํ๊ฐ(HandlerMethodReturnValueHandler)์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ํ์ํ ๊ฐ์ฒด๋ผ๊ณ ๋งํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ค๋ช ์ด ๊ธธ์ด์ก๋ค์! ๋ค์ RequestMappingHandlerAdapter์ ์ฝ๋๋ก ๋์๊ฐ๋ณด๊ฒ ์ต๋๋ค.
์ 10๋ฒ์งธ ๋ผ์ธ์ createInvocableHandlerMethod() ๋ฉ์๋๋ฅผ ํตํด ServletInvocableHandlerMethod ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ์ฝ๋๋ฅผ ๋ฐ๋ผ๊ฐ๋ณด๋ฉด bean, beanFactory, method, parameters ๋ฑ์ ๋ณ์๊ฐ ์ด๊ธฐํ๋์ด ์์ฑ์ด ๋ฉ๋๋ค.
ServletInvocableHandlerMethod ๊ฐ์ฒด์ ์์ฑ ๋ฐ ์ค์ ์ด ๋๋๋ฉด ์ 23๋ฒ์งธ ๋ผ์ธ์ invokeAndHandle() ๋ฉ์๋๊ฐ ์คํ๋ฉ๋๋ค.
invokeAndHandle()๋ Controller์ ๋ฉ์๋๋ฅผ ์คํํ๊ณ ๋ฐํ ๊ฐ์ ์ฒ๋ฆฌํ๋ ๋ฉ์๋์ ๋๋ค.
(์ฌ๊ธฐ์์ ๋ฆฌํด ํ์ ์ ๋ฐ๋ผ ModelAndView, ReponseEntity, ResponseBody ๋ฑ์ ๊ฐ Handler๊ฐ ์ฒ๋ฆฌํฉ๋๋ค.)
์ค์ ์ฒ๋ฆฌ๋ ๋ถ๋ชจ ํด๋์ค InvocableHandlerMethod์ invokeForRequest() ๋ฉ์๋์์ ์ด๋ฃจ์ด์ง๊ฒ ๋ฉ๋๋ค.
์ด์ฏค ๋๋ฉด ์ฒ์ ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญํ URI๊ฐ ๋ฌด์์ธ์ง ๊ธฐ์ต์ด ๋์ง ์์ ์๋ ์๊ธฐ์ ๊ธฐ์ต์ ๋์ด๋ ค๋ณด๋ฉด.... ๐ญ
URI์ Controller์ test() ๋ฉ์๋๋ฅผ ๋ฆฌ๋ง์ธ๋ ํ๋ ์ด์ ๋ ๋๋์ด! ๋ฉ์๋์ ํ๋ผ๋ฏธํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฐ์ด ์๋ ๋ก์ง์ ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ ๊ทธ๋ผ ๋ค์ InvocableHandlerMethod์ invokeForRequest() ๋ฉ์๋๋ฅผ ๋ณด๊ฒ ์ต๋๋ค.
invokeForRequest() ๋ฉ์๋์์๋ getMethodArgumentValues() ๋ฉ์๋๋ฅผ ํตํด Controller์ ๋ฉ์๋๋ฅผ ํธ์ถํ๊ธฐ ์ํด ํ์ํ ์ธ์ ๊ฐ๋ค์ ์ฒ๋ฆฌํฉ๋๋ค.
์ ์์ ์์๋ test() ๋ฉ์๋์ ์ฟผ๋ฆฌ ์คํธ๋ง์ ์ฒ๋ฆฌํ๊ธฐ ์ํด @RequestParam ์ด๋ ธํ ์ด์ ์ด ์ ์ธ๋์ด ์๋๋ฐ ์ด ์ธ์๋ @PathVariable, @RequestHeader ๋ฑ์ ์ด๋ ธํ ์ด์ ์ด ์คํ๋ง์ ArgumentResolver์ ์ํด ์ฒ๋ฆฌ๊ฐ ๋๊ณ , ์ด์ ๊ด๋ จํ ์์ ์ด ์ํ๋๋ ๊ณณ์ด getMethodArgumentValues() ๋ฉ์๋์ ๋๋ค.
getMethodArgumentValues() ๋ฉ์๋์ ๋ค์ด๋ฐ์ ํตํด ๋ฉ์๋์ ์ธ์ ๊ฐ์ ๊ฐ์ ธ์จ๋ค๋ ๊ฒ์ ์ ์ถํ ์ ์์ต๋๋ค.
์ค์ ๊ฐ์ ธ์ค๋ ๊ณผ์ ์ ํ๊ณ ๋ค์ด๊ฐ ๋ณด๋ฉด ๋ค์ ํด๋์ค๋ค์ ๊ฑฐ์ณ์ ์ธ์ ๊ฐ์ ๊ฐ์ ธ์ต๋๋ค... ๐ฑ
- InvocableHandlerMethod: this.resolvers.resolveArgument() -- (์ ์ฝ๋์์ 32๋ฒ์งธ ๋ผ์ธ)
- HandlerMethodArguemtnResolverComposite: resolveArgument()
- AbstractNamedValueMethodArgumentResolver: resolveArgument()
- RequestParamMethodArguemtnResolver: resolveName()
- ServletWebRequest: getParameterValues()
- RequestFacade: getParameterValues()
- Request: getParameterValues()
- Paramteters: getParameterValues() --- apache.tomcat.util.http
์์ ๊ฐ์ด ํ๊ณ ํ๊ณ ํ๊ณ .... ๊ณ์ ๋ค์ด๊ฐ๋ค๋ณด๋ฉด apache.tomcat์ Parametersํด๋์ค์ getParameterValues() ๋ฉ์๋์์ Map์ ์ด์ฉํด @RequestParam์ key์ ํด๋นํ๋ value๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
์ธ์๊ฐ์ ์ฒ๋ฆฌํ๊ณ ๋๋ฉด InvocableHandlerMethod๋ก ๋์์์ doInvoke() ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค.
์์ฒญ์ ์ฒ๋ฆฌํ๋ฉด ์ดํ ์๋ต์ ๋ํ ์ฒ๋ฆฌ๋ฅผ ํ๊ธฐ ์ํด ServletInvocableHandlerMethod์์ HandlerMethodReturnValueHandlerComposite๋ฅผ ์ฌ์ฉํ์ฌ ํ์ฒ๋ฆฌ๋ฅผ ์งํ ํฉ๋๋ค.
(์๋ ์ฝ๋์์ 135๋ฒ์งธ ๋ผ์ธ ~ )
์ HandlerMethodReturnValueHandlerComposite ํด๋์ค๋ List์ ๋ฑ๋ก๋์ด ์๋ Handler ์ค์ ์์ํ์ฌ ๋ฉ์๋ ๋ฐํ๊ฐ์ ์ฒ๋ฆฌํ๋ ์ปดํฌ์งํธ ํจํด์ ์ ์ฉํ๊ณ ์์ต๋๋ค.
HandlerMethodReturnValueHandler: handler method ์คํ ํ ๋ฐํ ๊ฐ์ ์ฒ๋ฆฌํ๊ธฐ ์ํ ์ ๋ต ์ธํฐํ์ด์ค
- supportsReturnType() ๋ฉ์๋๋ฅผ ํตํด ์ฃผ์ด์ง ๋ฉ์๋์ ๋ฆฌํด ํ์ ์ด ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ์ง ํ๋ณ
- handleReturnValue() ๋ฉ์๋์์ ์ฃผ์ด์ง ๋ฐํ ๊ฐ์ ํ ๋๋ก ์ฒ๋ฆฌ
HandlerAdapter๊ฐ Controller์๊ฒ ์์ฒญ์ด ๋๋๋ฉด ๋ค์์๋ ์๋ต์ ๋ํ ํ์ฒ๋ฆฌ๋ก returnValueHandlers๋ฅผ ํตํด ์ฒ๋ฆฌ๋ฉ๋๋ค.
API์ return type์ String์ธ๋ฐ์, ์ฌ๊ธฐ์ ๋ง๋ returnValueHandlers๋ RequestResponseBodyMethodProcessor ์ ๋๋ค.
(์ฃผ๋ก ์ฌ์ฉํ๋ ResponseEntity๊ฐ ๋ฆฌํด ํ์ ์ธ ๊ฒฝ์ฐ HttpEntityMethodProcessor์ Handler๋ก ์ฌ์ฉํฉ๋๋ค.)
๋ํ @RestController ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ModelAndView๊ฐ ์๋ String ๋ฌธ์์ด์ด ๊ทธ๋๋ก ์๋ต ๊ฐ์ผ๋ก ๋ฐํ์ด ๋ฉ๋๋ค.
RequestResponseBodyMethodProcessor ๋ด๋ถ์์๋ input, output Message๋ฅผ ์์ฑํ์ฌ AbstractMessageConverterMethodProcessor ์ถ์ ํด๋์ค์ writeWithMessageConverters() ๋ฉ์๋๋ฅผ ํธ์ถํ๊ณ , MediaType์ ๊ฒ์ฌํ์ฌ ์ ์ ํ HttpMessageConverter๋ฅผ ์ฐพ์ ์๋ต์ ์ฒ๋ฆฌํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค.
โ๏ธ ์ ๋ฆฌ
์ด์์ผ๋ก Spring์์ DispatcherServlet์ ๋ํด ์ดํด๋ณด์์ต๋๋ค.
DispatcherServlet์ด๋ผ๋ ํ๋์ ๊ฐ๋ ๋ง ๋ณด์๋ ๋ฌด์ํ ๋ง์ ๋ก์ง๊ณผ ์ฌ๋ฌ ํจํด๋ค, Spring์ ์ฒ ํ ๋ฑ์ ๋ณผ ์ ์์ด์ ์ข์์ต๋๋ค.
๋ํ ๋์์ธ ํจํด์ด ์ค์ ์ฝ๋ ์์์ ์ฌ์ฉ๋๋ ์์๋ฅผ ๋ณด๋ ๊ธฐ์กด์ ๊ฐ๋ ๋ง ๋ณด๋ ๊ฒ๊ณผ๋ ๋ฌ๋ฆฌ ์ดํด๊ฐ ๋ ์ ๋๋ ๊ฒ ๊ฐ์ต๋๋ค.
(์ฌ์ค DispatcherServlet ๋ด์์๋ ํต์ฌ ๊ธฐ๋ฅ๋ง ๋ดค๊ธฐ ๋๋ฌธ์ ๋ณด์ง ๋ชปํ ์ฝ๋๋ ๊ต์ฅํ ๋ง์ต๋๋ค...)
์คํ๋ง์ ๋งค์ฐ ์ค๋์ ์ ๋ง๋ค์ด์ง ํ๋ ์์ํฌ์๋ ๋ถ๊ตฌํ๊ณ ์์ง๊น์ง ์๋ฌด ๋ฌธ์ ์์ด ๋ง์ด ์ ์ฌ์ฉ๋๋ ๊ฒ์ ๋ณด๋ฉด... ์ ๋ง ๋๋จํ๋ค์.
์๋ฒฝํ ์ค๊ณ์ ์ํคํ ์ฒ๋ ์๊ฒ ์ง๋ง, ์ํํธ์จ์ด์ ์์ด์ ๊ต์ฅํ ์ค์ํ ์์๋ผ๊ณ ๋ค์๋ ๋๋ ๊ฒ ๊ฐ์ต๋๋ค.
๋ค์ ์๊ฐ์๋ ์์ฃผ ๊ฐ๋จํ DispatcherServlet์ ์ง์ ๋ง๋ค์ด๋ณด๋ฉฐ ์กฐ๊ธ ๋ ์ดํด๋๋ฅผ ๋์ฌ๋ณด๊ฒ ์ต๋๋ค.
๐ ์ฐธ๊ณ ๋ฌธ์
- https://docs.spring.io/spring-framework/docs/3.0.0.M4/spring-framework-reference/html/ch15s02.html
- https://terasolunaorg.github.io/guideline/5.0.1.RELEASE/en/Overview/SpringMVCOverview.html#overview-of-spring-mvc-processing-sequence
- https://mangkyu.tistory.com/18
- https://mangkyu.tistory.com/216
- https://tecoble.techcourse.co.kr/post/2021-07-15-dispatcherservlet-part-2/
๋๊ธ