Spring AOP - Hot-stock/backend GitHub Wiki

Spring AOP κ°œμš”

1. Spring AOPλž€?

AOP(Aspect-Oriented Programming, 관점 지ν–₯ ν”„λ‘œκ·Έλž˜λ°)λŠ” **νš‘λ‹¨ 관심사(Cross-Cutting Concerns)**λ₯Ό λΉ„μ¦ˆλ‹ˆμŠ€ 둜직과 λΆ„λ¦¬ν•˜μ—¬ λͺ¨λ“ˆν™”ν•˜λŠ” ν”„λ‘œκ·Έλž˜λ° νŒ¨λŸ¬λ‹€μž„μž…λ‹ˆλ‹€. νš‘λ‹¨ κ΄€μ‹¬μ‚¬λž€ λ‘œκΉ…, λ³΄μ•ˆ, νŠΈλžœμž­μ…˜ κ΄€λ¦¬μ²˜λŸΌ μ—¬λŸ¬ λͺ¨λ“ˆμ—μ„œ κ³΅ν†΅μœΌλ‘œ μ‚¬μš©λ˜λŠ” κΈ°λŠ₯을 μ˜λ―Έν•©λ‹ˆλ‹€. Spring AOPλŠ” 이듀 관심사λ₯Ό 핡심 λΉ„μ¦ˆλ‹ˆμŠ€ 둜직과 λΆ„λ¦¬ν•˜μ—¬ 효율적으둜 관리할 수 μžˆλ„λ‘ λ•μŠ΅λ‹ˆλ‹€.

λŒ€ν‘œμ μΈ AOP 적용 μ‚¬λ‘€λŠ” @Transactional μ–΄λ…Έν…Œμ΄μ…˜μž…λ‹ˆλ‹€. 이 μ–΄λ…Έν…Œμ΄μ…˜μ€ μ—¬λŸ¬ λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ— νŠΈλžœμž­μ…˜ 관리 κΈ°λŠ₯을 μ μš©ν•˜μ—¬ 일관성 있게 λͺ¨λ“ˆν™”λœ ν˜•νƒœλ‘œ 관리할 수 μžˆμŠ΅λ‹ˆλ‹€.


2. Spring AOPλ₯Ό μ‚¬μš©ν•˜λŠ” 이유

  • λͺ¨λ“ˆν™”: μ—¬λŸ¬ λͺ¨λ“ˆμ— 걸쳐 κ³΅ν†΅μ μœΌλ‘œ μ‚¬μš©λ˜λŠ” κΈ°λŠ₯을 μ€‘μ•™μ—μ„œ 관리할 수 μžˆμ–΄ μ½”λ“œ 쀑볡을 쀄이고, μœ μ§€λ³΄μˆ˜μ„±μ„ ν–₯μƒμ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.
  • μœ μ—°ν•œ 관리: λ‘œκΉ…, λ³΄μ•ˆ, νŠΈλžœμž­μ…˜ 관리와 같은 νš‘λ‹¨ 관심사λ₯Ό 핡심 λΉ„μ¦ˆλ‹ˆμŠ€ 둜직과 λ…λ¦½μ μœΌλ‘œ μ²˜λ¦¬ν•˜μ—¬ ν™•μž₯성을 높일 수 μžˆμŠ΅λ‹ˆλ‹€.

3. Spring AOP의 μ£Όμš” μš©μ–΄

3.1 PointCut

PointCut은 AOPκ°€ 적용될 μ§€μ μ΄λ‚˜ μ‹œμ μ„ μ •μ˜ν•©λ‹ˆλ‹€. Spring AOPμ—μ„œλŠ” 주둜 λ©”μ„œλ“œ 호좜 지점을 λŒ€μƒμœΌλ‘œ ν•˜λ©°, νŠΉμ • 쑰건에 λ§žλŠ” λ©”μ„œλ“œλ‚˜ ν΄λž˜μŠ€μ— AOPλ₯Ό μ μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 단, private λ©”μ„œλ“œμ—λŠ” AOPκ°€ μ μš©λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

3.2 JoinPoint

JoinPointλŠ” AOPμ—μ„œ λΆ€κ°€κΈ°λŠ₯(Advice)이 적용될 수 μžˆλŠ” 지점을 μ˜λ―Έν•˜λ©°, Spring AOPμ—μ„œλŠ” 주둜 λ©”μ„œλ“œ μ‹€ν–‰ 지점을 JoinPoint둜 μ‚¬μš©ν•©λ‹ˆλ‹€.

3.3 Advice

AdviceλŠ” AOPμ—μ„œ μ‹€μ œλ‘œ μˆ˜ν–‰ν•  λΆ€κ°€κΈ°λŠ₯을 μ •μ˜ν•©λ‹ˆλ‹€. λŒ€ν‘œμ μΈ μ’…λ₯˜λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

  • Before: λ©”μ„œλ“œ μ‹€ν–‰ μ „ λ™μž‘
  • After: λ©”μ„œλ“œ μ‹€ν–‰ ν›„ λ™μž‘
  • AfterReturning: λ©”μ„œλ“œκ°€ μ„±κ³΅μ μœΌλ‘œ λ°˜ν™˜λœ ν›„ λ™μž‘
  • AfterThrowing: λ©”μ„œλ“œ μ‹€ν–‰ 쀑 μ˜ˆμ™Έκ°€ λ°œμƒν–ˆμ„ λ•Œ λ™μž‘
  • Around: λ©”μ„œλ“œ μ‹€ν–‰ μ „ν›„ λͺ¨λ‘ λ™μž‘ν•˜λ©°, μ‹€ν–‰ 흐름을 μ œμ–΄ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

3.4 Aspect

AspectλŠ” Advice와 PointCut을 ν•˜λ‚˜μ˜ λͺ¨λ“ˆλ‘œ κ²°ν•©ν•œ κ²ƒμž…λ‹ˆλ‹€. νŠΈλžœμž­μ…˜ κ΄€λ¦¬λ‚˜ λ‘œκΉ… 같은 관심사λ₯Ό λͺ¨λ“ˆν™”ν•˜μ—¬ 관리할 수 μžˆμŠ΅λ‹ˆλ‹€.

3.5 Weaving

Weaving은 **Aspect(νš‘λ‹¨ 관심사)**λ₯Ό λŒ€μƒ 객체에 μ μš©ν•˜λŠ” κ³Όμ •μž…λ‹ˆλ‹€. Weaving은 컴파일 νƒ€μž„, λ‘œλ“œ νƒ€μž„, λŸ°νƒ€μž„μ— λ°œμƒν•  수 있으며, Spring AOPλŠ” 주둜 λŸ°νƒ€μž„μ— 동적 ν”„λ‘μ‹œλ₯Ό μ‚¬μš©ν•΄ Weaving을 μ²˜λ¦¬ν•©λ‹ˆλ‹€.


4. Spring AOP의 λ™μž‘ 방식

Spring AOPλŠ” **ν”„λ‘μ‹œ 객체(Proxy)**λ₯Ό μ‚¬μš©ν•˜μ—¬ λ™μž‘ν•©λ‹ˆλ‹€. Spring IoC μ»¨ν…Œμ΄λ„ˆκ°€ 빈(Bean) 객체λ₯Ό 생성할 λ•Œ, AOPκ°€ 적용된 κ°μ²΄λŠ” ν”„λ‘μ‹œλ‘œ 감싸져 λ“±λ‘λ©λ‹ˆλ‹€. 이후 ν•΄λ‹Ή 빈의 λ©”μ„œλ“œκ°€ 호좜되면, ν”„λ‘μ‹œ 객체가 λ¨Όμ € **λΆ€κ°€κΈ°λŠ₯(Advice)**을 μ‹€ν–‰ν•œ ν›„ 원본 λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ„ μˆ˜ν–‰ν•©λ‹ˆλ‹€.

ν”„λ‘μ‹œλŠ” 두 가지 λ°©μ‹μœΌλ‘œ μƒμ„±λ©λ‹ˆλ‹€:

  1. JDK 동적 ν”„λ‘μ‹œ: 빈이 μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜κ³  있으면 JDK 동적 ν”„λ‘μ‹œκ°€ μ‚¬μš©λ©λ‹ˆλ‹€.
  2. CGLIB ν”„λ‘μ‹œ: μΈν„°νŽ˜μ΄μŠ€κ°€ μ—†λŠ” 클래슀 기반 λΉˆμ€ CGLIB ν”„λ‘μ‹œκ°€ μ‚¬μš©λ©λ‹ˆλ‹€.

5. Spring AOP 적용 μ‹œμ 

Spring AOPλŠ” λŸ°νƒ€μž„ μ‹œμ μ— μ μš©λ©λ‹ˆλ‹€. ν”„λ‘μ‹œ 객체가 λŸ°νƒ€μž„μ— μƒμ„±λ˜μ–΄ λ©”μ„œλ“œ 호좜 μ‹œ AOPλ₯Ό μ μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. Spring AOPλŠ” 주둜 동적 ν”„λ‘μ‹œ 방식을 μ‚¬μš©ν•˜μ—¬, ν•„μš”ν•  λ•Œλ§ˆλ‹€ λΆ€κ°€κΈ°λŠ₯을 λ™μ μœΌλ‘œ μ²˜λ¦¬ν•©λ‹ˆλ‹€.

flowchart TD
    A[Spring AOP ν”„λ‘μ‹œ 생성 μš”μ²­] --> B{μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„ μ—¬λΆ€ 확인}
    
    B -->|μΈν„°νŽ˜μ΄μŠ€ 있음| C[JDK 동적 ν”„λ‘μ‹œ 생성]
    B -->|μΈν„°νŽ˜μ΄μŠ€ μ—†μŒ| D[CGLIB ν”„λ‘μ‹œ 생성]
    
    C --> E[ν”„λ‘μ‹œ 객체 생성 μ™„λ£Œ]
    D --> E[ν”„λ‘μ‹œ 객체 생성 μ™„λ£Œ]
    
    E --> F[ν”„λ‘μ‹œ 객체λ₯Ό IoC μ»¨ν…Œμ΄λ„ˆμ— 등둝]

6. Spring AOP와 Spring μΈν„°μ…‰ν„°μ˜ 차이점

  • Spring AOPλŠ” 주둜 λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ— λŒ€ν•œ νš‘λ‹¨ 관심사λ₯Ό μ²˜λ¦¬ν•˜λ©°, λ©”μ„œλ“œ λ ˆλ²¨μ—μ„œ λ™μž‘ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, λ©”μ„œλ“œ μ‹€ν–‰ μ „ν›„λ‚˜ μ˜ˆμ™Έ λ°œμƒ μ‹œμ— λΆ€κ°€κΈ°λŠ₯을 μ μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • Spring μΈν„°μ…‰ν„°λŠ” HTTP μš”μ²­/응닡 μ²˜λ¦¬μ— μ΄ˆμ μ„ λ§žμΆ”λ©°, μ›Ή λ ˆμ΄μ–΄μ—μ„œ λ™μž‘ν•©λ‹ˆλ‹€. μΈν„°μ…‰ν„°λŠ” μ»¨νŠΈλ‘€λŸ¬μ— λ„λ‹¬ν•˜κΈ° μ „ μš”μ²­μ„ κ°€λ‘œμ±„κ±°λ‚˜, 응닡을 ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ λ°˜ν™˜ν•˜κΈ° 전에 응닡을 κ°€λ‘œμ±„λŠ” 역할을 μˆ˜ν–‰ν•©λ‹ˆλ‹€.

7. AOP 적용 μ‹œ μ„±λŠ₯에 λ―ΈμΉ˜λŠ” 영ν–₯

  • AOP 적용 μ‹œ ν”„λ‘μ‹œ 객체 생성과 **λΆ€κ°€κΈ°λŠ₯(Advice)**의 싀행이 μΆ”κ°€λ˜κΈ° λ•Œλ¬Έμ— μ„±λŠ₯ μ˜€λ²„ν—€λ“œκ°€ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • 특히, CGLIB ν”„λ‘μ‹œλŠ” 클래슀 상속을 톡해 ν”„λ‘μ‹œλ₯Ό μƒμ„±ν•˜λ―€λ‘œ, JDK 동적 ν”„λ‘μ‹œλ³΄λ‹€ μ˜€λ²„ν—€λ“œκ°€ 더 클 수 μžˆμŠ΅λ‹ˆλ‹€.
  • λ‹€λ§Œ, 일반적인 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œλŠ” μ„±λŠ₯ μ˜€λ²„ν—€λ“œλŠ” 크지 μ•ŠμœΌλ©°, AOP둜 μ–»λŠ” μœ μ§€λ³΄μˆ˜μ„±κ³Ό μ½”λ“œ μž¬μ‚¬μš©μ„±μ΄ μ„±λŠ₯ 손싀을 상쇄할 수 μžˆμŠ΅λ‹ˆλ‹€.

8. AOP 적용 μ‹œ μ£Όμ˜μ‚¬ν•­

  • ν”„λ‘μ‹œμ˜ ν•œκ³„: Spring AOPλŠ” privateμ΄λ‚˜ final λ©”μ„œλ“œμ— μ μš©λ˜μ§€ μ•ŠμœΌλ©°, 빈 μŠ€μ½”ν”„μ—μ„œλ§Œ λ™μž‘ν•©λ‹ˆλ‹€.
  • μ„±λŠ₯ κ³ λ €: AOPκ°€ κ³Όλ„ν•˜κ²Œ 적용될 경우 μ„±λŠ₯ λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆμœΌλ―€λ‘œ, ν•„μš”ν•œ κ³³μ—λ§Œ μ‹ μ€‘ν•˜κ²Œ μ μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.