[Spring] Argument Resolver๋ฅผ ์ด์šฉํ•œ ์œ ์—ฐ์„ฑ ์žˆ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ ์ฒ˜๋ฆฌ

๋ฐ˜์‘ํ˜•

์„œ๋น„์Šค๋ฅผ ์šด์˜ํ•˜๋‹ค๋ณด๋ฉด ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿด ๋•Œ๋งˆ๋‹ค Controller ๋ถ€๋ถ„์—์„œ ์ด๋ฅผ ์ „์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ด๋ ‡๊ฒŒ ๋˜๋ฉด ๊ฐ Controller์— ์ „์ฒ˜๋ฆฌ ํ•ด์•ผ ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ํ•จ์ˆ˜ํ™” ํ•˜๊ฑฐ๋‚˜ Utils ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ , ์ด๋ฅผ ์˜์กด์„ฑ ์ฃผ์ž…ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๊ทธ๋‚˜๋งˆ ์ฝ”๋“œ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿฌ๋‚˜ Utils๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋งค๋ฒˆ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋Š” ๋ถˆํŽธํ•จ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ๋˜๋ฉด ์ฝ”๋“œ๊ฐ€ ์ค‘๋ณต๋˜๊ณ , ์ด๊ฒƒ์ด ์ปค์ง€๋ฉด ์—ญ์‹œ ์ฝ”๋“œ๊ฐ€ ๋‚œ์žกํ•ด์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. 

 

Spring์—์„œ๋Š” ์ด๋Ÿฌํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ณตํ†ต์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„๋œ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์žˆ๋Š”๋ฐ, ๊ทธ๊ฒƒ์ด ๋ฐ”๋กœ Argument Resolver์ž…๋‹ˆ๋‹ค. 

 

 

 

Spring Argument Resolver

API ์—”๋“œํฌ์ธํŠธ๋กœ๋ถ€ํ„ฐ ๋“ค์–ด์˜จ ๋ฐ์ดํ„ฐ(ํŒŒ๋ผ๋ฏธํ„ฐ)๋ฅผ ๊ฐ€๊ณตํ•˜์—ฌ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ๋ฝ‘๋Š” ๋“ฑ์˜ ๋กœ์ง์ด ํ•„์š”ํ•  ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•˜๋Š” Spring Argument Resolver๋Š” HandlerMethodArgumentResolver๋ฅผ ์ƒ์†ํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋งž๋Š” ์ƒˆ๋กœ์šด Resolver๋ฅผ ๋งŒ๋“ค๊ณ , ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰์‹œ, Resolver ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•จ์œผ๋กœ์จ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋ ‡๋‹ค๋ฉด ์ด Resolver๋Š” ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์ผ๊นŒ์š”?

 

Spring MVC๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ๋ฆ„์œผ๋กœ ์š”์ฒญ ์ฒ˜๋ฆฌ๊ฐ€ ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค.

 

  • ์‚ฌ์šฉ์ž๊ฐ€ ์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ†ตํ•ด ์š”์ฒญํ•˜๋ฉด DispatcherServlet์ด ์ด๋ฅผ ๋ฐ›์Œ
  • DispatcherServlet์€ ํ•ด๋‹น ์š”์ฒญ์— ๋งž๋Š” URI๋ฅผ HandlerMapping์—์„œ ๊ฒ€์ƒ‰

    • ์ด ๋•Œ, RequestMapping์œผ๋กœ ๊ตฌํ˜„ํ•œ API๋ฅผ ์ฐพ๊ฒŒ ๋˜๋Š”๋ฐ, ์ด๋“ค์€ RequestMappingHandlerAdapter๊ฐ€ ๋ชจ๋‘ ๊ฐ€์ง€๊ณ  ์žˆ์Œ.
    • ์›ํ•˜๋Š” Mapping์„ ์ฐพ์€ ๊ฒฝ์šฐ, ์ฒซ ๋ฒˆ์งธ๋กœ Intercepter๋ฅผ ์ฒ˜๋ฆฌ
    • Argument Resolver ์ฒ˜๋ฆฌ
    • Message Converter ์ฒ˜๋ฆฌ
  • Controller Method Invoke

๋ณดํ†ต ์ €๋Š” Filter์™€ Intercepter๋ฅผ API ์š”์ฒญ ์ค‘๊ฐ„์— ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ํŽธ์ž…๋‹ˆ๋‹ค. ํŠนํžˆ ๊ถŒํ•œ์„ ์š”๊ตฌํ•˜๊ฑฐ๋‚˜, ์ธ์ฆ์ด ํ•„์š”ํ•œ ๊ตฌ๊ฐ„์—์„œ๋Š” Filter๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์ด ๋•Œ Filter๋Š” DispatcherServlet ์š”์ฒญ์ด ์žˆ๊ธฐ ์ „์— ํ˜ธ์ถœ๋˜๊ณ  (Servlet์˜ ๋ผ์ดํ”„ ์‚ฌ์ดํด ์ฐธ๊ณ ) Intercepter์˜ ๊ฒฝ์šฐ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์š”์ฒญํ•œ API๋ฅผ ์ฐพ์€ ๋’ค์— ํ˜ธ์ถœ์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ ๊ตฌํ˜„์ฒด๋“ค์ด ์–ด๋–ป๊ฒŒ ํ˜ธ์ถœ๋˜๋Š”์ง€ ์•Œ๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

 

์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•˜๋Š” Argument Resolver๋Š” Intercepter ์š”์ฒญ ๋’ค์— ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. ์‚ฌ์‹ค ์ด ๋ถ€๋ถ„์„ ํ™•์ธํ•ด๋ณด๋ฉด, ๊ตณ์ด Argument Resolver๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ Intercepter๋ฅผ ๋ณ„๋„๋กœ ๊ตฌํ˜„ํ•ด ์ฒ˜๋ฆฌํ•ด๋„ ํฐ ๋ฌธ์ œ๊ฐ€ ์—†์ง€๋งŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋‹ค์–‘ํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์ด ์กด์žฌํ•œ๋‹ค๋ฉด ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ œ๊ณตํ•˜๋Š” Resolver๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ ๊ฐ ๋กœ์ง์„ ์›ํ•˜๋Š” ๊ตฌ๊ฐ„ ๋ณ„๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์€ ๋ฉ”๋ฆฌํŠธ๊ฐ€ ์žˆ์„์ง€๋„ ๋ชจ๋ฅด๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด๋“œ๋„ค์š”.

 

 

 

 

How to use

๊ทธ๋ ‡๋‹ค๋ฉด ์‹ค์ œ Spring Framework์—์„œ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ ์˜ˆ์‹œ๋กœ ์–ด๋–ค ๋ฌธ์ž์—ด์˜ ๊ฐ’์„ ์ฃผ์–ด๋„ ํด๋ผ์ด์–ธํŠธ์˜ ๋ธŒ๋ผ์šฐ์ € ์ •๋ณด๋ฅผ ํ™”๋ฉด์— ๋„์šฐ๋Š” API๋ฅผ ๋งŒ๋“ค์–ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋จผ์ € ํŒŒ๋ผ๋ฏธํ„ฐ ๊ตฌ๋ถ„์„ ์œ„ํ•œ ์–ด๋…ธํ…Œ์ด์…˜์„ ํ•œ ๊ฐœ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. ์ด ์–ด๋…ธํ…Œ์ด์…˜์€ API ์—”๋“œํฌ์ธํŠธ์—์„œ ํŠน์ • ๋ฐ์ดํ„ฐ์ž„์„ ๊ฐ€๋ฆฌํ‚ค๊ธฐ ์œ„ํ•œ ์šฉ๋„๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

 

API๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ฃผ๋Š” ๋ฌธ์ž์—ด์˜ ์ •๋ณด๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

 

์ด์ œ ํŠน์ • ์•„๊ทœ๋จผํŠธ ํƒ€์ž…์— ๋Œ€ํ•œ Resolver๋ฅผ ์ƒ์„ฑํ•ด์ค๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๋ฅผ ์œ„ํ•ด ์œ„์—์„œ ์–ด๋…ธํ…Œ์ด์…˜์„ ๋งŒ๋“ค์—ˆ์œผ๋ฏ€๋กœ HandlerMethodArgumentResolver๋ฅผ ์ƒ์†๋ฐ›์€ ํ›„ supportParameter ์ฝœ๋ฐฑ ํ•จ์ˆ˜์—์„œ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ์–ด๋…ธํ…Œ์ด์…˜์ธ์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

๋งˆ์ง€๋ง‰์œผ๋กœ resolveArgument ํ•จ์ˆ˜์—์„œ ํ•ด๋‹น ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ฐ˜ํ™˜๋˜๋Š”์ง€๋ฅผ ๊ตฌํ˜„ํ•ด์ฃผ๋ฉด ๋์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์–ด๋–ค ๋ฐ์ดํ„ฐ ๊ฐ’์ด ๋“ค์–ด์™€๋„ ๋ธŒ๋ผ์šฐ์ € ์ •๋ณด๋งŒ์„ ์ฃผ๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— Request ํŒŒ๋ผ๋ฏธํ„ฐ์—์„œ getHeader๋ฅผ ์ด์šฉํ•ด ํ—ค๋” ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

 

์ด์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์œ„์—์„œ ์ •์˜ํ•œ Resolver๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฉ”์ธ ํด๋ž˜์Šค์— WebMvcConfigurationSupport ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•˜๊ณ , addArgumentResolver ํ•จ์ˆ˜๋ฅผ ์žฌ์ •์˜ํ•˜์—ฌ ํ•ด๋‹น ํŒŒ๋ผ๋ฏธํ„ฐ์— ์žˆ๋Š” argumentResolver ๋ฆฌ์ŠคํŠธ์— ์œ„์—์„œ ๋งŒ๋“  Resolver๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

 

 

 

Test

์ด์ œ ๋ธŒ๋ผ์šฐ์ €์—์„œ API๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์œ„์™€ ๊ฐ™์ด ๋ธŒ๋ผ์šฐ์ €์˜ ์ •๋ณด๊ฐ€ ๋‚˜ํƒ€๋‚จ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

 

 

๋งˆ์น˜๋ฉฐ...

๊ธ€์“ฐ๊ธฐ ์ „๋ถ€ํ„ฐ ์–ด๋–ค ์˜ˆ์‹œ๋ฅผ ํ™œ์šฉํ• ๊นŒ๋ฅผ ๋งŽ์ด ๊ณ ๋ฏผํ•ด๋ดค์ง€๋งŒ ์‰ฝ๊ฒŒ ๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ ํ•ด๋ณผ๋งŒํ•œ ์˜ˆ์ œ๋ฅผ ์ฐพ์ง€ ๋ชปํ•œ ๊ฒŒ ์•„์‰ฌ์› ๋˜ ํฌ์ŠคํŠธ์˜€๋˜ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. 

 

์‹ค์ œ๋กœ ArgumentResolver๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›์„ ๋•Œ, ๋‹น์ดˆ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ์„ ์„œ๋ฒ„์— ์ฃผ๋Š” ๊ฒƒ์ด ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค๋งŒ ๊ทธ๋ ‡์ง€ ๋ชปํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ํ•œ ๊ฐ€์ง€๊ฐ€ ์žˆ๋Š”๋ฐ, ๊ทธ ๋ถ€๋ถ„ ์ค‘์— ํ•˜๋‚˜๋Š” ๋ฐ”๋กœ ์•”ํ˜ธํ™” ๋œ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค.

 

๋งŒ์•ฝ, ํด๋ผ์ด์–ธํŠธ์—์„œ ์•”ํ˜ธํ™”๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด, ๋จผ์ € ์ด๋ฅผ ๋ณตํ˜ธํ™” ํ•ด์•ผํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ View ๋‹จ์—์„œ ์ด๋ฅผ ๋ณตํ˜ธํ™” ํ•œ๋‹ค๋ฉด ๋ธŒ๋ผ์šฐ์ €์— ๋…ธ์ถœ๋  ๊ฐ€๋Šฅ์„ฑ์ด ํฌ๊ณ , ๊ทธ๋ ‡๊ฒŒ ๋˜๋ฉด ์„œ๋ฒ„์— ์ทจ์•ฝ์ ์ด ์ƒ๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์ด๋ฅผ ๋ณตํ˜ธํ™”ํ•˜๋Š” ๊ณผ์ •์€ ์„œ๋ฒ„์—์„œ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๊ฒ ์ฃ .

 

๋งŒ์•ฝ ๊ฐ API๋งˆ๋‹ค ์ด๋Ÿฐ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ๋ณธ๋ž˜ Controller๋งˆ๋‹ค ๋ณตํ˜ธํ™” ์ฒ˜๋ฆฌ ์ฝ”๋“œ๋ฅผ ๋„ฃ์–ด์•ผ ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ๋˜๋ฉด ์ฝ”๋“œ๊ฐ€ ์‹ฌ๊ฐํ•˜๊ฒŒ ์ง€์ €๋ถ„ํ•ด์ง€๊ณ , ์ค‘๋ณต ์ฝ”๋“œ๊ฐ€ ๋งŽ์•„์ง€๋ฉด์„œ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์ด ์ž์—ฐ์Šค๋ ˆ ๋–จ์–ด์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ ์ฒ˜๋ฆฌ๋ฅผ ์œ ์—ฐํ•˜๊ธฐ ์œ„ํ•ด Argument Resolver๊ฐ€ ์กด์žฌํ•˜๋ฉฐ ์ด๋ฅผ ์ž˜ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋ฐ˜์‘ํ˜•
TAGS.

Tistory Comments