๐ŸŒผ Spring - Interceptor์™€ AOP๋ฅผ ํ™œ์šฉํ•œ API ๋กœ๊น…

ํ•˜๋ฆฌ๋น„ยท2025๋…„ 4์›” 21์ผ
0

๐ŸŒผ Spring

๋ชฉ๋ก ๋ณด๊ธฐ
8/11

๐Ÿ“– Interceptor

Spring Mvc์—์„œ Controller์— ๋„๋‹ฌํ•˜๊ธฐ ์ „์ด๋‚˜ ํ›„์˜ ํ๋ฆ„์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค

  • HandlerInterceptor๋ฅผ implements ๋ฐ›๋Š”๋‹ค

  • ์ปจํŠธ๋กค๋Ÿฌ-๋””์ŠคํŒจ์ณ์„œ๋ธ”๋ฆฟ ์‚ฌ์ด์— ์œ„์น˜ํ•ด์„œ ํŠน์ • ์ปจํŠธ๋กค๋Ÿฌ์˜ ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ์ปจํŠธ๋กค

  • WebMvcConfigurer์— ๋“ฑ๋กํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค


๐Ÿ“Œ ๋ฉ”์„œ๋“œ

โœ”๏ธ preHandle()

  • ํ˜ธ์ถœ์‹œ์  : ์ปจํŠธ๋กค๋Ÿฌ ํ˜ธ์ถœ ์ „
  • ๋ฐ˜ํ™˜ ํƒ€์ž…์ด boolean - true ๋‹ค์Œ ์ธํ„ฐ์…‰ํ„ฐ or ์ปจํŠธ๋กค๋Ÿฌ ํ˜ธ์ถœ / false ์ž‘์—… ์ค‘๋‹จ

โœ”๏ธ postHandle()

  • ํ˜ธ์ถœ์‹œ์  : ์ปจํŠธ๋กค๋Ÿฌ ํ˜ธ์ถœ ํ›„
  • (๊ฒฐ๊ณผ๊ฐ’์ด ๋ฐ˜ํ™˜๋œ ์ดํ›„์— ์‹คํ–‰๋˜๊ธฐ์— )์˜ˆ์™ธ ๋ฐœ์ƒ์‹œ ์‹คํ–‰ โŒ

โœ”๏ธ afterCompletion()

  • ํ˜ธ์ถœ์‹œ์  : ๋ทฐ๊ฐ€ ๋žœ๋”๋ง๋œ ์ดํ›„
  • ์˜ˆ์™ธ ๋ฐœ์ƒ ์—ฌ๋ถ€์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์‘๋‹ต ์ „๋‹ฌ์‹œ ์‹คํ–‰

โ–ถ๏ธ ์‚ฌ์šฉ์˜ˆ์‹œ


โ–ช๏ธ AdminInterceptor

  • HandlerInterceptor์˜ ๊ตฌํ˜„ ํด๋ž˜์Šค ์ƒ์„ฑ
  • API์— ์ ‘๊ทผํ•œ ์‹œ๊ฐ„๊ณผ ์š”์ฒญ URI๋ฅผ ๋กœ๊ทธ์— ๋‚จ๊ธฐ๋„๋ก ํ–ˆ๋‹ค

โ–ช๏ธ Webconfig

  • ๋“ฑ๋กํ•ด์ค€๋’ค์— uri ๋ฒ”์œ„๋ฅผ ์ง€์ •ํ–ˆ๋‹ค
    ( ํ•ด๋‹น ์˜ˆ์ œ์—์„œ๋Š” admin ์ ‘๊ทผ์‹œ ๋กœ๊น…ํ•˜๋ผ๋Š” ์š”๊ตฌ์‚ฌํ•ญ์ด ์žˆ์—ˆ์Œ )

๐Ÿ“– AOP

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ณตํ†ต๊ธฐ๋Šฅ์„ ๋ถ„๋ฆฌํ•˜๊ณ  ๋ชจ๋“ˆํ™”ํ•œ๋‹ค (๋กœ๊น…, ํŠธ๋žœ์ ์…˜ ๊ด€๋ฆฌ, ๋ณด์•ˆ ๋“ฑ)

์ฐธ๊ณ ๋งํฌ

๐Ÿ“Œ Aspect

  • ๊ณตํ†ต ๊ด€์‹ฌ ์‚ฌํ•ญ์„ ์ •์˜ํ•˜๋Š” ๋ชจ๋“ˆ
    public AdminLogAspect(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

๐Ÿ“Œ Advice

  • Aspect์˜ ๋™์ž‘์„ ์ •์˜ํ•˜๋Š” ๋ถ€๋ถ„

    ์ด๋ฆ„๋™์ž‘ ์‹œ์ 
    @Before๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ „ ๋™์ž‘์ถ”๊ฐ€
    @AfterReturning๋ฉ”์„œ๋“œ ์ •์ƒ์ข…๋ฃŒ ํ›„ ๋™์ž‘์ถ”๊ฐ€
    @AfterThrowing๋ฉ”์„œ๋“œ ์˜ˆ์™ธ๋ฐœ์ƒ ์‹œ ๋™์ž‘์ถ”๊ฐ€
    @After๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰ ํ›„ ๋ฌด์กฐ๊ฑด ๋™์ž‘์ถ”๊ฐ€ (์„ฑ๊ณต/์˜ˆ์™ธ ๋ฐœ์ƒ ์—ฌ๋ถ€์™€ ๋ฌด๊ด€)
    @Around๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ „ํ›„ ๋ชจ๋‘ ๋™์ž‘์ถ”๊ฐ€ (๊ฐ€์žฅ ๊ฐ•๋ ฅํ•œ ์œ ํ˜•)

โœ”๏ธ ์˜ˆ์‹œ

 @Around("all()")
    public Object logging (ProceedingJoinPoint pjp) throws Throwable {
    ...

๐Ÿ“Œ Pointcut

  • ์–ด๋–ค ๋ฉ”์„œ๋“œ๊ฐ€ ์–ด๋–ค Advice๋ฅผ ๋ฐ›์„์ง€ ๊ฒฐ์ •ํ•˜๋Š” ํ‘œํ˜„์‹ โ‡ข ์ •๊ทœ์‹์œผ๋กœ ์ž‘์„ฑ
    ( ํŒจํ‚ค์ง€, ํŠน์ • ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ ๋“ฑ์œผ๋กœ ์ž‘์„ฑ ๊ฐ€๋Šฅ )

โœ”๏ธ ์˜ˆ์‹œ

    @Pointcut("execution(* org.example.expert.domain.user.controller.UserAdminController.*(..))")
    public void adminUser() {}

๐Ÿ“Œ Join Point

  • ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ์ค‘ ํŠน์ •ํ•œ ์‹œ์ ์„ ์˜๋ฏธ, Advice๊ฐ€ ์–ธ์ œ ์ ์šฉ๋  ์ง€
  • JoinPoint: ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ „๊นŒ์ง€๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ (@Before, @After ๋“ฑ์—์„œ ์‚ฌ์šฉ)
  • ProceedingJoinPoint: ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ž์ฒด๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Œ (@Around์—์„œ๋งŒ ์‚ฌ์šฉ)

๐Ÿ“Œ Weaving

  • Aspect๋ฅผ ๋Œ€์ƒ์ฝ”๋“œ์— ์ ์šฉํ•˜๋Š” ํ”„๋กœ์„ธ์Šค๋ฅผ ์˜๋ฏธ
  • ์ปดํŒŒ์ผ ์‹œ์ , ํด๋ž˜์Šค ๋กœ๋”ฉ ์‹œ์ , ๋Ÿฐํƒ€์ž„ ์‹œ์ ์— Weaving์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Œ

์ผ๋‹จ ๋ธ”๋กœ๊ทธ ๋ณด๊ณ  ๋ฌด๋‚œํ•˜๊ฒŒ ๊ตฌํ˜„,,

ํฌ์ธํŠธ ์ปท์œผ๋กœ ์ ์šฉํ•  ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ •๊ทœ์‹!!์œผ๋กœ ์ ์–ด์ค€๋‹ค~
์ฒจ์—” ์ฝ”๋ฉ˜ํŠธ ์œ ์ € ๋‚˜๋ˆด๋‹ค๊ฐ€
around๋กœ ๋˜ ๋ฒ”์œ„ ์ •ํ•ด์ฃผ๋Š”๋ฐ~~ ๊ฑ all๋กœ ํ•ฉ์นจ

๋ฌธ์ œ๋Š” ์š”์ฒญ ๋ณธ๋ฌธ๊ณผ ์‘๋‹ต ๋ณธ๋ฌธ์„ json ํ˜•ํƒœ๋กœ ๊ฐ€์ ธ์™€์„œ ๋กœ๊น…ํ•˜๋ผ๋Š” ์š”๊ตฌ์‚ฌํ•ญ์ด ์žˆ๋Š”๋ฐ..

๋ฌธ์ œ์ 

๋‹ค๋ฅธ ์ •๋ณด๋“ค ์ฒ˜๋Ÿผ ๊ทธ๋ƒฅ request.get~~ ์œผ๋กœ ๋ถˆ๋Ÿฌ์˜ฌ์ˆ˜์žˆ์„๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ•ด์„œ ๋ฉ”์„œ๋“œ๋ฅผ ์ฐพ์•„๋ณด์•˜์œผ๋‚˜
tomcat์—์„œ ํ•œ๋ฒˆ readํ•œ body๋Š” ๋‘๋ฒˆ ์ฝ์„ ์ˆ˜๊ฐ€ ์—†๋‹ค๊ณ  ํ•œ๋‹ค
๋‚ด๋ถ€์—์„œ ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ”์ธ๋”ฉํ• ๋•Œ ํ•œ๋ฒˆ ๋ฆฌ๋“œ ํ•˜๋ฏ€๋กœ,,
๋‚ด๊ฐ€ ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ „์— ์ฑ„๊ฐ€์„œ read ํ•ด๋ฒ„๋ฆฌ๋ฉด ๋ฐ”์ธ๋”ฉ์ด ๋ถˆ๊ฐ€ํ•œ ์ƒํ™ฉ!
๊ทธ๋Ÿผ ์–ด๋–ป๊ฒŒ ํ•˜๋ƒ?
์ฝ๋Š” ๋ฉ”์„œ๋“œ๋„ ๋‚ด๊ฐ€ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด์•ผํ•œ๋‹ค ์ด๋ง์ด๋‹ค~~
ํ•œ๋ฒˆ๋ฐ–์— ๋ชป์ฝ์–ด? ๊ทธ๋Ÿผ ์ง์ ‘ ๋งŒ๋“ค์–ด ์ฝ์–ด~~
ใ…Ž..
์ง„์งœ ์—ฌ๊ธฐ์„œ๋ถ€ํ„ฐ ๋ชจ๋ฅด๊ฒ ๋Š”๋ฐ
1.HttpServletRequestWrapper๋ฅผ ์ƒ์†๋ฐ›์•„ ๋ฉ”์„œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ•˜๋ฉด๋œ๋‹ค
2.ContentCachingRequestWrapper๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค -> ์š”๊ฑธ ์„ ํƒ! 1๋ฒˆ์„ ์ •๋ฆฌํ•œ ๊ธ€์ด ์–ด๋งˆ๋ฌด์‹œํ–ˆ๊ธฐ๋•Œ๋ฌธ

์œผ์•„์•„์•„์•„์•„์•…

ContentCachingRequestWrapper๋ฅผ ํ•„ํ„ฐ๋กœ ๋งŒ๋“ ๋‹ค
์™œ ํ•„ํ„ฐ๋กœ ๋งŒ๋“œ๋ƒ? ๊ฑ ํด๋ž˜์Šค๋กœ ๋งŒ๋“ค๋ฉด ์•ˆ๋Œ?
์•ˆ๋Œ ํ†ฐ์บฃ์ด ์ฝ์„๋ ค๊ณ  ๊ฐ€์ ธ๊ฐ€๊ธฐ ์ „์— ๊ฐ์‹ธ๋†”์•ผํ•˜๊ฑฐ๋“ ~

์•”ํŠผ ํ•„ํ„ฐ๋ฅผ ๋งŒ๋“ค๊ณ  ํ•„ํ„ฐ๋ฅผ ๋“ฑ๋กํ•œ๋‹ค
์ ์šฉ๋ฒ”์œ„๋Š” ๊ฑ ์ „์ฒด๋กœ ํ•จ ์–ด์ฐจํ”ผ aop์—์„œ ์ ์šฉ๋ฒ”์œ„๊ฐ€ ์ •ํ•ด์ ธ์žˆ์Œ(ํฌ์ธํŠธ์ปท)
+์–ธ์ œ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ์˜ ์š”์ฒญ ๋ณธ๋ฌธ์„ ๋กœ๊น…ํ•ด์•ผํ• ์ง€ ๋ชจ๋ฅด๋ฏ€๋กœ~

๊ทธ๋ฆฌ๊ณ  ์‚ฌ์šฉ์„ ํ•˜๋ฉด๋˜๋Š”๋ฐ
์ผ๋‹จ ๋ธ”๋กœ๊ทธ์—์„œ if๋กœ instanceof๋กœ ํ™•์ธํ•˜๊ธธ๋ž˜ ๋”ฐ๋ผํ•˜๊ณ  ์ด์œ ๋ฅผ ์ฐพ์•„๋ณด๋‹ˆ
๋‚ด๊ฐ€๋ถˆ๋Ÿฌ์˜จ request๊ฐ€ ์•„์•„๊นŒ ๊ฐ์‹ธ๋’€๋˜!! ๊ฑ”๊ฐ€ ๋งž๋Š”์ง€ ๊ฒ€์ฆํ•˜๋Š” ๊ฑฐ๋ผ๋Š”๋ฐ
๊ทธ๋ž˜์„œ ๊ฒ€์ฆ์„ ๊ผญ ํ•ด์•ผํ•˜๋ƒ๊ณ ? ์•ˆํ•ด๋ฐจ๋‹ค ๋ชจ๋ฅธ๋‹ค !! ๊ธ‰ํ•˜๋‹ˆ๊นŒ ํ•˜๋ž€๋Œ€๋กœ ํ–ˆ๋‹ค
์•”ํŠผ๊ฐ„์— ์ŠคํŠธ๋ง์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋ฉด ๋~

์‘๋‹ต ๋ณธ๋ฌธ์€ ๊ฑ objectMapper๋กœ ๊ธ์–ด์˜ค๋ฉด ๋œ๋‹ค~
์–˜๋Š” ์š”์ฒญ์ด ์•„๋‹ˆ๋ผ ์‘๋‹ต์ด๋ผ์„œ ํ†ฐ์บฃ ์ด์ƒˆ๊ธฐ๊ฐ€ ์ฝ์„์ผ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค..

0๊ฐœ์˜ ๋Œ“๊ธ€