โ˜• Backend/Spring, Spring Boot

[Spring] Spring AOP

devCloud 2026. 3. 31. 16:37
728x90

๐ŸŒฑ Spring AOP (๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ) ๊ฐœ๋…

1. AOP๋ž€? (Aspect-Oriented Programming)

AOP๋Š” ๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์œผ๋กœ, ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ๊ณตํ†ต์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ํšก๋‹จ ๊ด€์‹ฌ์‚ฌ(Cross-Cutting Concerns)๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ๋ชจ๋“ˆ์„ฑ์„ ๋†’์ด๋Š” ํŒจ๋Ÿฌ๋‹ค์ž„์ž…๋‹ˆ๋‹ค.

ํšก๋‹จ ๊ด€์‹ฌ์‚ฌ ์˜ˆ์‹œ

  • ๋กœ๊น…(Logging), ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ, ๋ณด์•ˆ, ์„ฑ๋Šฅ ์ธก์ •, ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋“ฑ

AOP๊ฐ€ ํ•„์š”ํ•œ ์ด์œ 

  • ์ค‘๋ณต ์ œ๊ฑฐ: ์—ฌ๋Ÿฌ ๋ฉ”์„œ๋“œ์— ํฉ์–ด์ง„ ๊ณตํ†ต ๋กœ์ง์„ ํ•œ ๊ณณ์—์„œ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ๋ณ€๊ฒฝ ์ง€์  ๋‹จ์ผํ™”: ๊ณตํ†ต ๋กœ์ง ์ˆ˜์ • ์‹œ Advice ํ•˜๋‚˜๋งŒ ๋ณ€๊ฒฝํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
  • ํ•ต์‹ฌ ๋กœ์ง ์ง‘์ค‘: ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ฐ€๋…์„ฑ์„ ๋†’์ž…๋‹ˆ๋‹ค.

2. ์ฃผ์š” ์šฉ์–ด ๋ฐ Advice ์ข…๋ฅ˜

  • Aspect: Advice + Pointcut์„ ํ•ฉ์นœ ๋ชจ๋“ˆ์ž…๋‹ˆ๋‹ค.
  • Advice: ์‹ค์ œ ์ˆ˜ํ–‰๋  ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ ๋กœ์ง์ž…๋‹ˆ๋‹ค.
  • Pointcut: Advice๋ฅผ ์–ด๋””์— ์ ์šฉํ• ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ์ง€์ ์ž…๋‹ˆ๋‹ค.
  • JoinPoint: Advice๊ฐ€ ์ ์šฉ ๊ฐ€๋Šฅํ•œ ์‹œ์ (์ฃผ๋กœ ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์‹œ์ )์ž…๋‹ˆ๋‹ค.
  • Target: ํ•ต์‹ฌ ๋กœ์ง์„ ๊ฐ€์ง„ ์‹ค์ œ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.

Advice ์‹คํ–‰ ์‹œ์ 

  • @Before: ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ „
  • @After: ๋ฉ”์„œ๋“œ ์‹คํ–‰ ํ›„ (์ •์ƒ/์˜ˆ์™ธ ๋ฌด๊ด€)
  • @AfterReturning: ๋ฉ”์„œ๋“œ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ–ˆ์„ ๋•Œ
  • @AfterThrowing: ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ค‘ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ
  • @Around: ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ „ํ›„๋ฅผ ๋ชจ๋‘ ์ œ์–ด (๊ฐ€์žฅ ๊ฐ•๋ ฅํ•จ)

3. ์ฝ”๋“œ ์˜ˆ์‹œ (@Aspect)

@Aspect
@Component
public class LoggingAspect {
    
    // com.example.service ํŒจํ‚ค์ง€ ํ•˜์œ„์˜ ๋ชจ๋“  ๋ฉ”์„œ๋“œ์— ์ ์šฉ
    @Around("execution(* com.example.service.*.*(..))")
    public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("[Before] ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ „");
        
        Object result = joinPoint.proceed(); // ์‹ค์ œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ํ˜ธ์ถœ
        
        log.info("[After] ๋ฉ”์„œ๋“œ ์‹คํ–‰ ํ›„");
        return result;
    }
}

4. Spring AOP์˜ ์›๋ฆฌ

ํ”„๋ก์‹œ ํŒจํ„ด (Proxy Pattern)

์Šคํ”„๋ง์€ ์‹ค์ œ ํƒ€๊ฒŸ ๊ฐ์ฒด ๋Œ€์‹  ํ”„๋ก์‹œ(๊ฐ€์งœ) ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋นˆ์„ ํ˜ธ์ถœํ•˜๋ฉด ํ”„๋ก์‹œ๊ฐ€ ๋จผ์ € ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ•๋‹ˆ๋‹ค.
  • ํ”„๋ก์‹œ๊ฐ€ Advice(๋ถ€๊ฐ€ ๊ธฐ๋Šฅ)๋ฅผ ์‹คํ–‰ํ•œ ๋’ค, ์‹ค์ œ Target(ํ•ต์‹ฌ ๋กœ์ง)์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

๋Ÿฐํƒ€์ž„ ์œ„๋น™ (Runtime Weaving)

  • ์œ„๋น™: Advice์™€ ํ•ต์‹ฌ ๋กœ์ง์„ ์—ฐ๊ฒฐํ•˜๋Š” ์ž‘์—…์ž…๋‹ˆ๋‹ค.
  • ์Šคํ”„๋ง์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์‹œ์ (๋Ÿฐํƒ€์ž„)์— ํ”„๋ก์‹œ๋ฅผ ํ†ตํ•ด ์œ„๋น™์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์žˆ์œผ๋ฉด JDK Dynamic Proxy, ํด๋ž˜์Šค๋งŒ ์žˆ์œผ๋ฉด CGLIB ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ์š”์•ฝ ๐Ÿ’ก

AOP๋Š” ํ”„๋ก์‹œ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ  ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ์ฃผ์ž…ํ•˜๋Š” ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ์˜ ์ค‘๋ณต์„ ์ค„์ด๊ณ  ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ๊ทน๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

728x90