์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ์˜ SecurityContextHolder๋ฅผ ์‚ฌ์šฉํ•˜์…จ๋˜๋ฐ ThreadLocal์— ๋Œ€ํ•ด์„œ ์ด์•ผ๊ธฐํ•ด๋ณด์„ธ์š”.

์Šคํ”„๋ง ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋‚ด๋ถ€์ ์œผ๋กœ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ํด๋ž˜์Šค ์ค‘ ํ•˜๋‚˜๋Š” ThreadLocal ์ด๋ผ๋Š” ์ž๋ฐ” ๊ธฐ๋ณธ ํด๋ž˜์Šค๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. ์‹ ์ž… ์›น ๊ฐœ๋ฐœ์ž๋“ค์— ๋Œ€ํ•œ ์ธํ„ฐ๋ทฐ๋ฅผ ์ง„ํ–‰ํ•˜๋‹ค๋ณด๋ฉด ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์™€ ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ–ˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋‚ด๋ถ€์ ์œผ๋กœ ์–ด๋–ค ๋™์ž‘์„ ํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฑฐ๋‚˜ ThreadLocal ์ด๋ผ๋Š” ์ž๋ฐ” ์–ธ์–ด์—์„œ์˜ ๊ธฐ๋ณธ ์ง€์‹์— ๋Œ€ํ•ด์„œ ๋“ค์–ด๋ณด์ง€ ๋ชปํ•œ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค. ๋Œ€๋ถ€๋ถ„ ์œ ๋ช…ํ•œ ๊น€์˜ํ•œ๋‹˜์˜ ๊ฐ•์˜๋ฅผ ์ˆ˜๊ฐ•ํ–ˆ๋‹ค๊ณ  ์ด๋ ฅ์„œ์— ๊ธฐ์žฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ThreadLocal์— ๋Œ€ํ•œ ๋ถ€๋ถ„์„ ๋‹ค๋ฃจ์ง€ ์•Š์•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ ์ฐพ์•„๋ณด๋‹ˆ ThreadLocal์ด๋ผ๋Š” ๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ๋„ ์–ธ๊ธ‰ํ•˜๊ณ  ์žˆ๊ธฐ์— ์ˆ˜๊ฐ•์ž๋“ค์ด ์ผ๋ถ€ ๋‚ด์šฉ์„ ์Šค์Šค๋กœ ์ƒ๋žตํ•˜๊ณ  ๋„˜์–ด๊ฐ”์„ ๊ฒƒ ๊ฐ™๋‹ค.

XXXContextHolder

โ• org.springframework.web.context.request.RequestContextHolder
โ• org.springframework.context.i18n.LocaleContextHolder
โ• org.springframework.security.core.context.SecurityContextHolder

์œ„์™€ ๊ฐ™์ด ContextHolder๋กœ ๋๋‚˜๋„๋ก ์ด๋ฆ„์ด ์ •์˜๋œ ํด๋ž˜์Šค๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ThreadLocal์„ ์‚ฌ์šฉํ•˜๋„๋ก ๊ตฌํ˜„๋˜์–ด์žˆ๋Š” ๋Œ€ํ‘œ์ ์ธ ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์˜ ํด๋ž˜์Šค์ด๋‹ค. ์ธํ…”๋ฆฌ์ œ์ด IDEA๋ฅผ ํ†ตํ•ด์„œ ์œ„ ํด๋ž˜์Šค๋“ค์„ ์‚ฌ์šฉํ•˜๋Š” ๋‹ค๋ฅธ ํด๋ž˜์Šค๋ฅผ ๋”ฐ๋ผ๊ฐ€๋ณด๋ฉด ์–ด๋–ป๊ฒŒ ํ™œ์šฉํ•˜๊ณ  ์žˆ๋Š”์ง€๋ฅผ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ RequestContextHolder์™€ LocaleContextHolder์˜ ์ƒ์„ฑ๊ณผ ์‚ญ์ œ๋Š” RequestContextFilter์—์„œ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ SecurityContextHolder๋Š” SecurityContextHolderFilter์—์„œ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ์Œ์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.

์ด์™€ ๊ฐ™์ด ์ผ๋ฐ˜์ ์ธ ์ž๋ฐ” ๊ฐœ๋ฐœ์ž๋“ค๋„ ThreadLocal๊ณผ Filter๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ๋™์ผํ•œ ์Šค๋ ˆ๋“œ ๋‚ด์—์„œ๋Š” ์–ธ์ œ๋“ ์ง€ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋Š” ํŒจํ„ด์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋Š” ์ด์•ผ๊ธฐ์ด๋‹ค. ThreadLocal ์ž์ฒด๊ฐ€ ์Šค๋ ˆ๋“œ ๋‚ด์— ์ •๋ณด ๊ณต์œ ๋ฅผ ์œ„ํ•œ ์ง€์—ญ ๋ณ€์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

RequestContextFilter

RequestContextFilter์—์„œ๋Š” HttpServletRequest์˜ ๋กœ์ผ€์ผ ์ •๋ณด์™€ ServletRequestAttributes๋ฅผ ThreadLocal์— ์ €์žฅํ•˜๋„๋ก ๊ตฌํ˜„๋˜์–ด์žˆ๋‹ค. ๋‹ค๋ฅธ ํ•„ํ„ฐ๋ฅผ ๊ฑฐ์น˜๊ณ  ๋‚œ ํ›„ ๋ฐ˜๋“œ์‹œ ThreadLocal์— ์žˆ๋Š” ์ •๋ณด๋“ค์„ ์ œ๊ฑฐํ•˜๋„๋ก ๋˜์–ด์žˆ๋Š” ๋ถ€๋ถ„์ด ์ค‘์š”ํ•˜๋‹ค. RequestContextHolder์— ์ €์žฅ๋˜๋Š” ํด๋ž˜์Šค๋Š” ServletRequestAttributes ์ด๋ฉฐ ์ด์ „์— ๊ณต์œ ํ•œ ๋ ˆ๋””์Šค ์žฅ์•  ํšŒ๊ณ ์—์„œ๋„ ๋‚ด๋ถ€ ๊ตฌํ˜„์„ ์‚ดํŽด๋ณธ ํด๋ž˜์Šค์— ํ•ด๋‹นํ•œ๋‹ค.

SecurityContextHolderFilter

์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ 5.7+ ๋ถ€ํ„ฐ๋Š” SecurityContextPersistenceFilter๊ฐ€ ์•„๋‹Œ SecurityContextHolderFilter๋กœ ๋Œ€์ฒด๋˜์–ด ์‚ฌ์šฉ๋œ๋‹ค. SecurityContextPersistenceFilter๋กœ ์ฒ˜๋ฆฌ๋˜๋˜ ๊ฒƒ์ด SecurityContextHolderFilter ์—์„œ๋Š” ์–ด๋– ํ•œ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„๋˜์—ˆ๋Š”์ง€ ๋น„๊ตํ•ด๋ณด์•„๋„ ์ข‹์€ ํ•™์Šต์ด ๋  ๊ฒƒ ๊ฐ™๋‹ค. Supplier ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ™œ์šฉํ•˜์—ฌ SecurityContext๋ฅผ ์ง€์—ฐ๋˜์–ด ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ณ€๊ฒฝํ•˜์˜€๋‹ค.

๋งŽ์€ ํšŒ์‚ฌ์—์„œ ์‹ ์ž… ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๋ฐ”๋ผ๋Š” ์—ญ๋Ÿ‰ ์ค‘ ๊ธฐ๋ณธ ์ง€์‹์— ๋Œ€ํ•œ ์ด์•ผ๊ธฐ๋Š” ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ์ˆ ์— ๋Œ€ํ•ด์„œ ๋‚ด๋ถ€์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋ณธ ๊ฐœ๋…์ด ์žˆ๋Š”์ง€ ์ฐพ์•„๋ณด๋Š” ํŽธ์ธ๊ฐ€๋ฅผ ๋งํ•˜๋Š”๊ฒŒ ์•„๋‹๊นŒ? ๋น„๋ก ์‹ ์ž… ์›น ๊ฐœ๋ฐœ์ž๋กœ ์ผํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‹ค๋ฌด ๊ธฐ์ˆ ์— ๋Œ€ํ•œ ์—ญ๋Ÿ‰์„ ๋ฐฐ์šฐ๊ณ  ์–ดํ•„ํ•˜๋Š” ๊ฑด ์–ด์ฉ” ์ˆ˜ ์—†๋Š” ์ƒํ–ฅ ํ‰์ค€ํ™”๋œ ๋ถ€๋ถ„์ด ์žˆ์ง€๋งŒ ๊ธฐ๋ณธ์ ์ธ ์ง€์‹๊ณผ ๊ด€๋ จ๋œ ์ง€์‹์€ ์—†๋Š”์ง€ ์ฐพ์•„๋ณด๊ณ  ์ง€์†์ ์ธ ํ•™์Šต์— ๋Œ€ํ•œ ์–ดํ•„๋„ ํ•„์š”ํ•  ๊ฒƒ์ด๋‹ค.