Spring Core Advanced

μ˜ν•œλ‹˜μ˜ μŠ€ν”„λ§ 핡심 원리 - κ³ κΈ‰νŽΈarrow-up-right κ°•μ˜λ₯Ό μš”μ•½ν•œ λ‚΄μš©μž…λ‹ˆλ‹€.

Projectarrow-up-right

⭐️ ThreadLocal

λ™μ‹œμ„± 문제

  • λ‹€μˆ˜μ˜ μ“°λ ˆλ“œκ°€ λ™μ‹œμ— 같은 μΈμŠ€ν„΄μŠ€ ν•„λ“œ 값을 λ³€κ²½ν•˜λ©΄μ„œ λ°œμƒν•˜λŠ” 문제

  • μŠ€ν”„λ§ 빈처럼 싱글톀 객체의 ν•„λ“œλ₯Ό λ³€κ²½ν•˜λ©° μ‚¬μš©ν•  λ•Œ 주의

ThreadLocal

  • νŠΉμ • μŠ€λ ˆλ“œλ§Œ μ ‘κ·Όν•  수 μžˆλŠ” νŠΉλ³„ν•œ μ €μž₯μ†Œ

  • 각 μŠ€λ ˆλ“œλ§ˆλ‹€ λ³„λ„μ˜ λ‚΄λΆ€ μ €μž₯μ†Œ 제곡

  • νŠΉμ • μŠ€λ ˆλ“œ λ‘œμ»¬μ„ λͺ¨λ‘ μ‚¬μš©λ©΄ ThreadLocal.remove() 호좜둜 μ €μž₯된 값을 λ°˜λ“œμ‹œ 제거

    • μŠ€λ ˆλ“œ 풀을 μ‚¬μš©ν•  경우(ex. WAS) μŠ€λ ˆλ“œ 둜컬 값을 μ œκ±°ν•˜μ§€ μ•ŠμœΌλ©΄, μ‚¬μš©μžBκ°€ μ‚¬μš©μžA 데이터λ₯Ό μ‘°νšŒν•˜κ²Œ λ˜λŠ” 문제 λ°œμƒ

    • μŠ€λ ˆλ“œλŠ” μŠ€λ ˆλ“œ 풀을 톡해 μž¬μ‚¬μš©λ˜μ§€ λ•Œλ¬Έμ— μŠ€λ ˆλ“œ λ‘œμ»¬μ—μ„œ μ œκ±°λ˜μ§€ μ•Šκ³  λ‚¨μ•„μžˆλŠ” 데이터λ₯Ό λ‹€λ₯Έ μ‚¬μš©μžκ°€ μ‘°νšŒν•  수 있게 λœλ‹€.

commitarrow-up-right

Template Method Pattern

λ‹€ν˜•μ„±(상속과 μ˜€λ²„λΌμ΄λ”©)을 ν™œμš©ν•΄μ„œ λ³€ν•˜λŠ” λΆ€λΆ„(핡심 κΈ°λŠ₯)κ³Ό λ³€ν•˜μ§€ μ•ŠλŠ” λΆ€λΆ„(둜그 좔적기, νŠΈλžœμž­μ…˜..)을 λΆ„λ¦¬ν•˜λŠ” λ””μžμΈ νŒ¨ν„΄

ꡬ쑰

Result

μΈμŠ€ν„΄μŠ€ 호좜 κ³Όμ •

Result
  • λΆ€λͺ¨ ν΄λž˜μŠ€μ— ν…œν”Œλ¦Ώ(λ³€ν•˜μ§€ μ•ŠλŠ” λΆ€λΆ„)을 μ •μ˜ν•˜κ³ , 일뢀 λ³€κ²½λ˜λŠ” λ‘œμ§μ€ μžμ‹ ν΄λž˜μŠ€μ— μ •μ˜

  • μžμ‹ ν΄λž˜μŠ€κ°€ 전체 ꡬ쑰λ₯Ό λ³€κ²½ν•˜μ§€ μ•Šκ³ , νŠΉμ • λΆ€λΆ„λ§Œ μž¬μ •μ˜

  • κ²°κ΅­ 상속과 μ˜€λ²„λΌμ΄λ”©μ„ ν†΅ν•œ λ‹€ν˜•μ„±μœΌλ‘œ 문제 ν•΄κ²°

  • ν΄λž˜μŠ€λŠ” 단 ν•œ 개의 μ±…μž„μ„ κ°€μ Έμ•Ό ν•œλ‹€λŠ” 단일 μ±…μž„ 원칙(Single Responsibility Principle)을 잘 μ§€ν‚€λŠ” νŒ¨ν„΄

  • 단, μƒμ†μ—μ„œ μ˜€λŠ” 단점듀이 쑴재

    • κ°•ν•œ μ˜μ‘΄μ„±μœΌλ‘œ λΆ€λͺ¨ 클래슀의 κΈ°λŠ₯을 μ‚¬μš©ν•˜μ§€ μ•Šλ”λΌλ„ λΆ€λͺ¨ 클래슀λ₯Ό μ•Œμ•„μ•Ό ν•˜κ³ 

    • λΆ€λͺ¨ 클래슀λ₯Ό μˆ˜μ •ν•˜λ©΄ μžμ‹ ν΄λž˜μŠ€μ— 영ν–₯을 쀄 수 있음

    • 상속 ꡬ쑰둜 인해 μƒμ„±λ˜λŠ” ν΄λž˜μŠ€λ‚˜ 읡λͺ… λ‚΄λΆ€ 클래슀의 λ³΅μž‘μ„±

읡λͺ… λ‚΄λΆ€ 클래슀

  • μ§€μ • 이름이 μ—†κ³  클래슀 내뢀에 μ„ μ–Έλ˜λŠ” 클래슀

  • 객체 μΈμŠ€ν„΄μŠ€ 생성과 λ™μ‹œμ— 생성할 클래슀λ₯Ό 상속 받은 μžμ‹ 클래슀 μ •μ˜

Template Example

commitarrow-up-right

Strategy Pattern

Template Method Pattern 의 μƒμ†μœΌλ‘œ μΈν•œ 단점을 μœ„μž„μœΌλ‘œ ν•΄κ²°ν•œ λ””μžμΈ νŒ¨ν„΄

ꡬ쑰

Result

μ „λž΅ νŒ¨ν„΄ μ‹€ν–‰ κ³Όμ •

Result
  • λ³€ν•˜μ§€ μ•ŠλŠ” 뢀뢄을 Context(λ³€ν•˜μ§€ μ•ŠλŠ” ν…œν”Œλ¦Ώ)에, λ³€ν•˜λŠ” 뢀뢄을 Strategy(λ³€ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜) μΈν„°νŽ˜μ΄μŠ€μ— 두고, ν•΄λ‹Ή κ΅¬ν˜„μ²΄λ₯Ό 톡해 문제λ₯Ό ν•΄κ²°

    • Context에 μ›ν•˜λŠ” Strategy κ΅¬ν˜„μ²΄ μ£Όμž…

    • ν΄λΌμ΄μ–ΈνŠΈλŠ” Context μ‹€ν–‰

    • ContextλŠ” Context 둜직 μ‹œμž‘

    • Context 둜직 쀑간에 strategy.call() 호좜둜 μ£Όμž… 받은 Strategy 둜직 μ‹€ν–‰

    • ContextλŠ” λ‚˜λ¨Έμ§€ 둜직 μ‹€ν–‰

commitarrow-up-right

읡λͺ… 클래슀 μ‚¬μš©

  • Context/Strategy μ„  쑰립, ν›„ μ‹€ν–‰ 방식에 적합

    • ν•„λ“œμ— Strategy μ €μž₯ λ°©μ‹μ˜ μ „λž΅ νŒ¨ν„΄

  • ν•œ 번 쑰립 이후 Context μ‹€ν–‰λ§Œ ν•˜λ©΄ 끝

    • μŠ€ν”„λ§ λ‘œλ”© μ‹œμ μ— μ˜μ‘΄κ΄€κ³„ μ£Όμž…μ„ 톡해 쑰립 ν›„ μš”μ²­μ„ μ²˜λ¦¬ν•˜λŠ” 것과 μœ μ‚¬

  • 단점은, 쑰립 이후에 μ „λž΅ 변경이 λ²ˆκ±°λ‘œμ›€ (싱글톀 μ‚¬μš© μ‹œ λ™μ‹œμ„± 이슈 λ“± κ³ λ € 사항이 쑴재)

commitarrow-up-right

Template Callback Pattern

μ „λž΅μ„ ν•„λ“œλ‘œ κ°€μ§€μ§€ μ•Šκ³  νŒŒλΌλ―Έν„°λ‘œ 전달

  • μ „λž΅ νŒ¨ν„΄μ—μ„œ ν…œν”Œλ¦Ώκ³Ό 콜백 뢀뢄이 κ°•μ‘°λœ νŒ¨ν„΄(GOF νŒ¨ν„΄μ€ μ•„λ‹ˆκ³  μŠ€ν”„λ§ λ‚΄λΆ€μ—μ„œ λΆˆλ¦¬μ›€)

  • μ½”λ“œκ°€ Call 이후 μ½”λ“œλ₯Ό λ„˜κ²¨μ€€ 곳의 Back μ—μ„œ μ‹€ν–‰(CallBack..)

  • μŠ€ν”„λ§μ—μ„œ XxxTemplate(JdbcTemplate, RestTemplate, TransactionTemplate, RedisTemplate) ν˜•νƒœλŠ” ν…œν”Œλ¦Ώ 콜백 νŒ¨ν„΄μ΄ μ‚¬μš©λ˜μ–΄ λ§Œλ“€μ–΄μ§„ 클래슀

Result
  • νŒŒλΌλ―Έν„°μ— Strategy 전달 λ°©μ‹μ˜ μ „λž΅ νŒ¨ν„΄

  • μ‹€ν–‰ν•  λ•Œλ§ˆλ‹€ μ „λž΅μ„ μœ μ—°ν•˜κ²Œ λ³€κ²½

  • 단점은, μ‹€ν–‰ν•  λ•Œλ§ˆλ‹€ μ „λž΅μ„ 계속 μ§€μ •ν•΄ μ£Όμ–΄μ•Ό ν•˜λŠ” λ²ˆκ±°λ‘œμ›€

commitarrow-up-right

μ½œλ°±μ„ μ‚¬μš©ν•  경우 읡λͺ… λ‚΄λΆ€ ν΄λž˜μŠ€λ‚˜ λžŒλ‹€λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 편리

단, μ—¬λŸ¬ κ³³μ—μ„œ ν•¨κ»˜ μ‚¬μš©λ  경우 μž¬μ‚¬μš©μ„ μœ„ν•΄ μ½œλ°±μ„ λ³„λ„μ˜ 클래슀둜 λ§Œλ“œλŠ”κ²Œ μ’‹μŒ

  • Context -> Template

  • Strategy -> Callback

Example

적용

Proxy

ν”„λ‘μ‹œμ˜ μ£Όμš” κΈ°λŠ₯

  • μ ‘κ·Ό μ œμ–΄

    • κΆŒν•œμ— λ”°λ₯Έ μ ‘κ·Ό 차단

    • 캐싱

    • μ§€μ—° λ‘œλ”©

  • λΆ€κ°€ κΈ°λŠ₯ μΆ”κ°€

    • κΈ°μ‘΄ 제곡 κΈ°λŠ₯에 λΆ€κ°€ κΈ°λŠ₯ μˆ˜ν–‰

    • ex. μš”μ²­/응닡 κ°’ λ³€ν˜•, μΆ”κ°€ 둜그

  • 단점

    • λŒ€μƒ 클래슀만 λ‹€λ₯Ό 뿐 λ‘œμ§μ€ μœ μ‚¬ν•˜κ³ , λŒ€μƒ 클래슀 개수만큼 ν”„λ‘μ‹œ 클래슀 생성 ν•„μš”

    • 동적 ν”„λ‘μ‹œ κΈ°μˆ μ„ 톡해 ν”„λ‘μ‹œ 클래슀λ₯Ό ν•˜λ‚˜λ§Œ λ§Œλ“€μ–΄μ„œ λͺ¨λ“  곳에 적용 κ°€λŠ₯

Proxy Pattern

ν”„λ‘μ‹œλ₯Ό μ μš©ν•˜μ—¬ 접근을 μ œμ–΄ν•˜λŠ” νŒ¨ν„΄

μ˜λ„(intent) : λ‹€λ₯Έ κ°œμ²΄μ— λŒ€ν•œ 접근을 μ œμ–΄ν•˜κΈ° μœ„ν•΄ λŒ€λ¦¬μž 제곡

Result
  • μ‹€μ œ 객체와 ν΄λΌμ΄μ–ΈνŠΈμ˜ μ½”λ“œλ₯Ό λ³€κ²½ν•˜μ§€ μ•Šκ³ , ν”„λ‘μ‹œ λ„μž…μœΌλ‘œ 접근을 μ œμ–΄

  • μ‹€μ œ ν΄λΌμ΄μ–ΈνŠΈ μž…μž₯μ—μ„œ ν”„λ‘μ‹œ 객체가 μ£Όμž…λ˜μ—ˆλŠ”μ§€, μ‹€μ œ 객체가 μ£Όμž…λ˜μ—ˆλŠ”μ§€ μ•Œ 수 μ—†μŒ

ν”„λ‘μ‹œ 객체

ν”„λ‘μ‹œ 객체 적용

commitarrow-up-right

Decorator Pattern

ν”„λ‘μ‹œλ₯Ό μ μš©ν•˜μ—¬ λΆ€κ°€ κΈ°λŠ₯을 μΆ”κ°€ν•˜λŠ” νŒ¨ν„΄

μ˜λ„(intent) : 객체에 μΆ”κ°€ μ±…μž„(κΈ°λŠ₯)을 λ™μ μœΌλ‘œ μΆ”κ°€ν•˜κ³ , κΈ°λŠ₯ ν™•μž₯을 μœ„ν•œ μœ μ—°ν•œ λŒ€μ•ˆ 제곡

Result
  • client -> messageDecorator(proxy) -> realComponent 객체 의쑴

  • client -> timeDecorator(proxy) -> messageDecorator(proxy) -> realComponent 객체 의쑴

적용

ν”„λ‘μ‹œλ₯Ό μ‚¬μš©ν•΄ κΈ°μ‘΄ μ½”λ“œλ₯Ό μˆ˜μ •ν•˜μ§€ μ•Šκ³  μƒˆλ‘œμš΄ κΈ°λŠ₯을 λ„μž…

  • μ‹€μ œ 객체 λŒ€μ‹  ν”„λ‘μ‹œ 객체λ₯Ό μŠ€ν”„λ§ 빈으둜 등둝(ν”„λ‘μ‹œ λ‚΄λΆ€μ—μ„œ μ‹€μ œ 객체 μ°Έμ‘°)

    • ν”„λ‘μ‹œ κ°μ²΄λŠ” μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆκ°€ μŠ€ν”„λ§ 빈으둜 κ΄€λ¦¬ν•˜κ³  μžλ°” νž™ λ©”λͺ¨λ¦¬μ— μ˜¬λΌκ°€λŠ” 반면

    • μ‹€μ œ κ°μ²΄λŠ” μžλ°” νž™ λ©”λͺ¨λ¦¬μ—λŠ” μ˜¬λΌκ°€μ§€λ§Œ μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆκ°€ κ΄€λ¦¬ν•˜μ§€ μ•ŠμŒ

      • ν”„λ‘μ‹œ 객체λ₯Ό ν†΅ν•΄μ„œ μ°Έμ‘°λ˜λŠ” 쑴재

μΈν„°νŽ˜μ΄μŠ€μ™€ κ΅¬ν˜„ 클래슀(μŠ€ν”„λ§ 빈 μˆ˜λ™ 등둝)

μΈν„°νŽ˜μ΄μŠ€ μ—†λŠ” ꡬ체 클래슀(μŠ€ν”„λ§ 빈 μˆ˜λ™ 등둝)

  • 클래슀 기반 ν”„λ‘μ‹œ λ„μž…

    • μΈν„°νŽ˜μ΄μŠ€κ°€ 없더라도 λ‹€ν˜•μ„±μœΌλ‘œ 클래슀λ₯Ό μƒμ†λ°›μ•„μ„œ ν”„λ‘μ‹œλ₯Ό 적용

    • μΈν„°νŽ˜μ΄μŠ€ 기반 ν”„λ‘μ‹œμ— λΉ„ν•΄ μ—¬λŸ¬ 단점이 쑴재

      • λΆ€λͺ¨ 클래슀의 μƒμ„±μž 호좜 ν•„μš”

      • final 클래슀 상속 λΆˆκ°€

      • final λ©”μ„œλ“œ μ˜€λ²„λΌμ΄λ”© λΆˆκ°€

μ»΄ν¬λ„ŒνŠΈ μŠ€μΊ” μŠ€ν”„λ§ 빈 μžλ™ 등둝

동적 ν”„λ‘μ‹œ

λ¦¬ν”Œλ ‰μ…˜

  • 클래슀/λ©”μ„œλ“œ 메타정보λ₯Ό λ™μ μœΌλ‘œ νšλ“ν•˜κ³ , μ½”λ“œλ₯Ό λ™μ μœΌλ‘œ 호좜

  • λŸ°νƒ€μž„μ— λ™μž‘ν•˜λ―€λ‘œ 컴파일 μ‹œμ μ— 였λ₯˜λ₯Ό μž‘μ„ 수 μ—†λŠ” 단점

    • 일반적으둜 μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 것이 μ’‹κ³ , ν”„λ ˆμž„μ›Œν¬ κ°œλ°œμ΄λ‚˜ 일반적인 곡톡 μ²˜λ¦¬κ°€ ν•„μš”ν•  경우 λΆ€λΆ„μ μœΌλ‘œ μ£Όμ˜ν•΄μ„œ μ‚¬μš©

JDK 동적 ν”„λ‘μ‹œ

λŒ€μƒ ν΄λž˜μŠ€μ— μΈν„°νŽ˜μ΄μŠ€κ°€ μžˆμ„ 경우(μΈν„°νŽ˜μ΄μŠ€ 기반 ν”„λ‘μ‹œ)

  • μΈν„°νŽ˜μ΄μŠ€ 기반 동적 ν”„λ‘μ‹œ 생성(λŸ°νƒ€μž„)

    • 각각의 λŒ€μƒ 객체 ν”„λ‘μ‹œλ₯Ό 직접 λ§Œλ“€μ§€ μ•Šκ³ , ν”„λ‘μ‹œ 동적 생성(JDK 동적 ν”„λ‘μ‹œ) ν›„ InvocationHandler μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„μ²΄(ν”„λ‘μ‹œ 둜직 μ •μ˜) ν•˜λ‚˜λ₯Ό 곡톡 μ‚¬μš©

    • 동적 ν”„λ‘μ‹œλŠ” ν•Έλ“€λŸ¬ 둜직만 ν˜ΈμΆœν•˜κ³  λ©”μ„œλ“œμ™€ 인수λ₯Ό κ°€μ§€κ³  μ‹€ν–‰

    • 객체의 μΈν„°νŽ˜μ΄μŠ€κ°€ λ°˜λ“œμ‹œ ν•„μš”ν•΄μ„œ, 클래슀만 μžˆλŠ” κ²½μš°μ—λŠ” μ μš©ν•  수 μ—†λŠ” ν•œκ³„

InvocationHandler.java

TimeInvocationHandler.java (InvocationHandler μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„μ²΄)

  • Object proxy : ν”„λ‘μ‹œ μžμ‹ 

  • Method method : ν˜ΈμΆœν•œ λ©”μ„œλ“œ

  • Object[] args : λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  λ•Œ μ „λ‹¬ν•œ 인수

적용 예제

μ‹€ν–‰ μˆœμ„œ

  1. JDK 동적 ν”„λ‘μ‹œμ˜ call() μ‹€ν–‰ proxy.call();

  2. JDK 동적 ν”„λ‘μ‹œλŠ” InvocationHandler.invoke() 호좜

  3. TimeInvocationHandler λ‚΄λΆ€ 둜직 μˆ˜ν–‰ 및 method.invoke(target, args) 호좜.

  4. target의 μ‹€μ œ 객체 AImpl μΈμŠ€ν„΄μŠ€μ˜ call() μ‹€ν–‰

  5. AImpl μΈμŠ€ν„΄μŠ€μ˜ call() 싀행이 λλ‚˜λ©΄ TimeInvocationHandler 응닡

examplearrow-up-right

적용

Result

CGLIB

λŒ€μƒ ν΄λž˜μŠ€μ— μΈν„°νŽ˜μ΄μŠ€κ°€ 없을 경우(ꡬ체 클래슀 기반 ν”„λ‘μ‹œ)

  • μΈν„°νŽ˜μ΄μŠ€ 없이 ꡬ체 클래슀 기반(상속) 동적 ν”„λ‘μ‹œ 생성

    • 상속 μ‚¬μš©μœΌλ‘œ μΈν•œ μ œμ•½

      • λΆ€λͺ¨ 클래슀의 κΈ°λ³Έ μƒμ„±μž ν•„μš”

      • final ν΄λž˜μŠ€λŠ” 상속 λΆˆκ°€

      • final λ©”μ„œλ“œλŠ” μ˜€λ²„λΌμ΄λ”© λΆˆκ°€

  • JDK 동적 ν”„λ‘μ‹œ μ‹€ν–‰ λ‘œμ§μ— InvocationHandlerλ₯Ό μ œκ³΅ν•˜λ“―, MethodInterceptor 제곡

MethodInterceptor.java

CGLIB 예제arrow-up-right

Spring Proxy Factory

ν”„λ‘μ‹œ 생성은 ProxyFactory λ‘œμ§μ€ Advice

남은 문제점.. -> 빈 ν›„μ²˜λ¦¬κΈ°λ‘œ 처리 κ°€λŠ₯

  • λ„ˆλ¬΄ λ§Žμ€ 섀정이 ν•„μš”

    • μŠ€ν”„λ§ 빈이 100개 μžˆλ‹€λ©΄, ν”„λ‘μ‹œ λΆ€κ°€ κΈ°λŠ₯ μ μš©μ„ μœ„ν•΄ 100개의 동적 ν”„λ‘μ‹œ 생성 ν•„μš”

  • μ»΄ν¬λ„ŒνŠΈ μŠ€μΊ”μ„ μ‚¬μš©ν•˜λŠ” 경우 Proxy Factory 적용 λΆˆκ°€λŠ₯

    • μ‹€μ œ 객체가 μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆ μŠ€ν”„λ§ 빈으둜 λ“±λ‘λœ μƒνƒœμ΄λ―€λ‘œ

γ…‡ μΈν„°νŽ˜μ΄μŠ€κ°€ μžˆλŠ” 경우 JDK 동적 ν”„λ‘μ‹œ, κ·Έλ ‡μ§€ μ•Šμ€ κ²½μš°μ—λŠ” CGLIB 적용

  • 동적 ν”„λ‘μ‹œλ₯Ό ν†΅ν•©ν•΄μ„œ λ§Œλ“€μ–΄μ£ΌλŠ” ProxyFactory 제곡

  • μΈν„°νŽ˜μ΄μŠ€κ°€ 있으면 JDK 동적 ν”„λ‘μ‹œ μ‚¬μš©, ꡬ체 클래슀만 μžˆλ‹€λ©΄ CGLIB μ‚¬μš©(default)

Result

γ…‡ JDK 동적 ν”„λ‘μ‹œ, CGLIB λ₯Ό ν•¨κ»˜ μ‚¬μš©ν•  경우 λΆ€κ°€ κΈ°λŠ₯ 적용

  • InvocationHandler,MethodInterceptor λ₯Ό μ‹ κ²½μ“°μ§€ μ•Šκ³ , Advice 만 생성

  • org.aopalliance.intercept.MethodInterceptor κ΅¬ν˜„μœΌλ‘œ Advice 생성

Result

γ…‡ νŠΉμ • 쑰건에 ν”„λ‘μ‹œ λ‘œμ§μ„ μ μš©ν•˜λŠ” 곡톡 κΈ°λŠ₯

  • Pointcut κ°œλ… λ„μž…μœΌλ‘œ μΌκ΄€μ„±μžˆκ²Œ ν•΄κ²°

MethodInterceptor κ΅¬ν˜„μœΌλ‘œ Advice 생성 예제arrow-up-right

Spring Proxy Factory μ‚¬μš© 예제arrow-up-right

Pointcut, Advice, Advisor

핡심. ν•˜λ‚˜μ˜ Target 에 μ—¬λŸ¬ AOPκ°€ λ™μ‹œμ— μ μš©λ˜μ–΄λ„, μŠ€ν”„λ§μ˜ AOPλŠ” Target λ§ˆλ‹€ ν•˜λ‚˜μ˜ ν”„λ‘μ‹œλ§Œ 생성

Result

Pointcut : λŒ€μƒ μ—¬λΆ€λ₯Ό ν™•μΈν•˜λŠ” ν•„ν„° μ—­ν• 

  • λΆ€κ°€ κΈ°λŠ₯을 μ–΄λŠ 곳에 적용/λ―Έμ μš©ν• μ§€ νŒλ‹¨ν•˜λŠ” 필터링 둜직

  • 주둜 ν΄λž˜μŠ€μ™€ λ©”μ„œλ“œ μ΄λ¦„μœΌλ‘œ 필터링

  • μŠ€ν”„λ§ 제곡 Pointcutarrow-up-right

    • μŠ€ν”„λ§μ΄ μ œκ³΅ν•˜λŠ” λŒ€ν‘œμ μΈ Pointcut

      • AspectJExpressionPointcut : aspectJ ν‘œν˜„μ‹ λ§€μΉ­ (μ‹€λ¬΄μ—μ„œ 주둜 많이 μ‚¬μš©)

      • NameMatchMethodPointcut : λ©”μ„œλ“œ 이름 기반 λ§€μΉ­ν•œλ‹€

      • JdkRegexpMethodPointcut : JDK μ •κ·œ ν‘œν˜„μ‹ 기반 λ§€μΉ­

      • TruePointcut : 항상 μ°Έ λ°˜ν™˜

      • AnnotationMatchingPointcut : μ• λ…Έν…Œμ΄μ…˜ λ§€μΉ­

  • Pointcut 의 두 κ°€μ§€ μ—­ν•  ‼️

    • 생성 단계 -> ν”„λ‘μ‹œ 적용 μ—¬λΆ€ νŒλ‹¨ (클래슀, λ©”μ„œλ“œ 쑰건 λͺ¨λ‘ 비ꡐ)

    • μ‚¬μš© 단계 -> advice(λΆ€κ°€ κΈ°λŠ₯) 적용 μ—¬λΆ€ νŒλ‹¨

Advice : λΆ€κ°€ κΈ°λŠ₯ 둜직 λ‹΄λ‹Ή

  • ν”„λ‘μ‹œκ°€ ν˜ΈμΆœν•˜λŠ” λΆ€κ°€ κΈ°λŠ₯(=ν”„λ‘μ‹œ 둜직)

Advisor : ν•˜λ‚˜μ˜ Pointcut, ν•˜λ‚˜μ˜ Adviceλ₯Ό κ°–λŠ” 것

⭐️ BeanPostProcessor

빈 μ €μž₯μ†Œμ— 객체λ₯Ό λ“±λ‘ν•˜κΈ° 직전 μ‘°μž‘μ„ ν•˜κ³  싢을 경우 빈 ν›„μ²˜λ¦¬κΈ°(BeanPostProcessor)λ₯Ό μ‚¬μš©(빈 생성 ν›„ 처리 μš©λ„)

  • Spring Proxy Factory 의 단점(λ§Žμ€ μ„€μ •, μ»΄ν¬λ„ŒνŠΈ μŠ€μΊ” λŒ€μƒ 객체 적용의 어렀움)을 ν•΄κ²°

Result
  1. 생성: μŠ€ν”„λ§ 빈 λŒ€μƒ 객체 생성(@Bean, @ComponentScan..)

  2. 전달: μƒμ„±λœ 객체λ₯Ό 빈 μ €μž₯μ†Œμ— λ“±λ‘ν•˜κΈ° 직전에 빈 ν›„μ²˜λ¦¬κΈ°μ— 전달

  3. ν›„ 처리 μž‘μ—…: 빈 ν›„μ²˜λ¦¬κΈ°λŠ” μ „λ‹¬λœ μŠ€ν”„λ§ 빈 객체λ₯Ό μ‘°μž‘ν•˜κ±°λ‚˜ λ‹€λ₯Έ 객체둜 λ°”λ€ŒμΉ˜κΈ° κ°€λŠ₯

  4. 등둝: 빈 ν›„μ²˜λ¦¬κΈ°λŠ” 빈 λ°˜ν™˜. 전달 된 λΉˆμ„ κ·ΈλŒ€λ‘œ λ°˜ν™˜ν•˜λ©΄ ν•΄λ‹Ή 빈이 λ“±λ‘λ˜κ³ , λ°”κΏ”μΉ˜κΈ° ν•˜λ©΄ λ‹€λ₯Έ 객체가 빈 μ €μž₯μ†Œμ— 등둝

BeanPostProcessor interface

  • 빈 ν›„μ²˜λ¦¬κΈ°λ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄ BeanPostProcessor μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„ ν›„ μŠ€ν”„λ§ 빈 등둝

  • postProcessBeforeInitialization : 객체 생성 이후 @PostConstruct 같은 μ΄ˆκΈ°ν™” λ°œμƒ μ „ ν˜ΈμΆœλ˜λŠ” 포슀트 ν”„λ‘œμ„Έμ„œ

  • postProcessAfterInitialization : 객체 생성 이후 @PostConstruct 같은 μ΄ˆκΈ°ν™” λ°œμƒ ν›„ ν˜ΈμΆœλ˜λŠ” 포슀트 ν”„λ‘œμ„Έμ„œ

적용

  • BeanPostProcessor λ₯Ό μ‚¬μš©ν•΄μ„œ μ‹€μ œ 객체 λŒ€μ‹  ν”„λ‘μ‹œλ₯Ό μŠ€ν”„λ§ 빈으둜 등둝 κ°€λŠ₯

    • μˆ˜λ™ 등둝 λΉˆμ„ ν¬ν•¨ν•˜μ—¬ μ»΄ν¬λ„ŒνŠΈ μŠ€μΊ”μ„ μ‚¬μš©ν•˜λŠ” λΉˆκΉŒμ§€ λͺ¨λ‘ ν”„λ‘μ‹œ 적용이 κ°€λŠ₯

    • μ„€μ • νŒŒμΌμ—μ„œ ν”„λ‘μ‹œλ₯Ό μƒμ„±ν•˜λŠ” μ½”λ“œκ°€ λΆˆν•„μš”

Result

빈 ν›„μ²˜λ¦¬κΈ° 적용arrow-up-right

μŠ€ν”„λ§ 제곡 빈 ν›„μ²˜λ¦¬κΈ°

μŠ€ν”„λ§ AOP λŠ” Pointcut 을 μ‚¬μš©ν•΄μ„œ ν”„λ‘μ‹œ 적용 λŒ€μƒ μ—¬λΆ€ 체크

  • ν”„λ‘μ‹œκ°€ ν•„μš”ν•œ κ³³μ—λ§Œ ν”„λ‘μ‹œ 적용

  • ν”„λ‘μ‹œ λ‚΄λΆ€ νŠΉμ • λ©”μ„œλ“œκ°€ 호좜 λ˜μ—ˆμ„ λ•Œ μ–΄λ“œλ°”μ΄μŠ€ 적용

μ˜μ‘΄μ„± 좔가둝

  • aspectjweaver: aspectJ κ΄€λ ¨ 라이브러리 등둝 및 μŠ€ν”„λ§ λΆ€νŠΈκ°€ AOP κ΄€λ ¨ 클래슀λ₯Ό μžλ™μœΌλ‘œ μŠ€ν”„λ§ λΉˆμ— 등둝

    • AnnotationAwareAspectJAutoProxyCreator 빈 ν›„μ²˜λ¦¬κΈ°κ°€ μŠ€ν”„λ§ λΉˆμ— μžλ™μœΌλ‘œ 등둝

AutoProxyCreator

Result
  • μžλ™μœΌλ‘œ ν”„λ‘μ‹œλ₯Ό μƒμ„±ν•΄μ£ΌλŠ” 빈 ν›„μ²˜λ¦¬κΈ°

  • μŠ€ν”„λ§ 빈으둜 λ“±λ‘λœ Advisor 듀을 μžλ™μœΌλ‘œ μ°Ύμ•„μ„œ ν”„λ‘μ‹œκ°€ ν•„μš”ν•œ 곳에 μžλ™μœΌλ‘œ ν”„λ‘μ‹œ 적용

  • ν”„λ‘μ‹œλ₯Ό λͺ¨λ“  곳에 μƒμ„±ν•˜λŠ” 것은 λΉ„μš© λ‚­λΉ„μ΄λ―€λ‘œ 포인트컷으둜 필터링 ν›„ ν•„μš”ν•œ 곳에 μ΅œμ†Œν•œμ˜ ν”„λ‘μ‹œ 적용

  • Advisor1, Advisor2, 3, 4.. κ°€ μ œκ³΅ν•˜λŠ” 포인트컷의 쑰건을 λͺ¨λ‘ λ§Œμ‘±ν•˜λ”λΌλ„ ν”„λ‘μ‹œλ₯Ό ν•œ 개만 μƒμ„±ν•˜κ³  ν”„λ‘μ‹œλŠ” 쑰건에 λ§Œμ‘±ν•˜λŠ” μ—¬λŸ¬ Advisorλ₯Ό μ†Œμœ 

μŠ€ν”„λ§μ΄ μ œκ³΅ν•˜λŠ” 빈 ν›„μ²˜λ¦¬κΈ° 적용arrow-up-right

AspectJExpressionPointcut

  • AOP에 νŠΉν™”λœ μ •λ°€ν•œ 포인트컷 ν‘œν˜„μ‹(AspectJ) 적용

  • μŠ€ν”„λ§μ— ν”„λ‘μ‹œλ₯Ό μ μš©ν•˜λ €λ©΄ Advisor(pointcut, advice 둜 ꡬ성)λ₯Ό λ§Œλ“€μ–΄μ„œ μŠ€ν”„λ§ 빈으둜 λ“±λ‘ν•˜λ©΄ μžλ™ ν”„λ‘μ‹œ 생성기가 μžλ™μœΌλ‘œ 처리

  • μžλ™ ν”„λ‘μ‹œ μƒμ„±κΈ°λŠ” μŠ€ν”„λ§ 빈으둜 λ“±λ‘λœ Advisor 듀을 μ°Ύκ³ , μŠ€ν”„λ§ λΉˆλ“€μ— μžλ™μœΌλ‘œ 포인트컷이 λ§€μΉ­λ˜λŠ” 경우 ν”„λ‘μ‹œλ₯Ό 적용

@Aspect μ• λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•΄μ„œ 더 νŽΈλ¦¬ν•˜κ²Œ pointcut κ³Ό advice λ₯Ό λ§Œλ“€κ³  ν”„λ‘μ‹œμ— μ μš©ν•  수 μžˆλ‹€.

⭐️ @Aspect Proxy

  • @Aspect μ• λ…Έν…Œμ΄μ…˜μœΌλ‘œ pointcut κ³Ό advice 둜 κ΅¬μ„±λ˜μ–΄ μžˆλŠ” Advisor 의 νŽΈλ¦¬ν•œ 생성 지원

  • μžλ™ ν”„λ‘μ‹œ 생성기(AnnotationAwareAspectJAutoProxyCreator)λ₯Ό 톡해 @Aspect λ₯Ό μ°Ύμ•„μ„œ Advisor 둜 λ³€ν™˜/μ €μž₯, Advisor 기반으둜 ν•„μš”ν•œ 곳에 ν”„λ‘μ‹œλ₯Ό 생성

Result

@Aspect -> Advisor λ³€ν™˜ κ³Όμ •

  1. μ‹€ν–‰: μŠ€ν”„λ§ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ‘œλ”© μ‹œμ μ— μžλ™ ν”„λ‘μ‹œ 생성기 호좜

  2. λͺ¨λ“  @Aspect 빈 쑰회: μžλ™ ν”„λ‘μ‹œ μƒμ„±κΈ°λŠ” μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆμ—μ„œ @Aspect 이 뢙은 μŠ€ν”„λ§ λΉˆμ„ λͺ¨λ‘ 쑰회

  3. μ–΄λ“œλ°”μ΄μ € 생성: @Aspect μ–΄λ“œλ°”μ΄μ € λΉŒλ”(BeanFactoryAspectJAdvisorsBuilder)λ₯Ό 톡해 @Aspect μ• λ…Έν…Œμ΄μ…˜ 정보λ₯Ό 기반으둜 μ–΄λ“œλ°”μ΄μ € 생성

  4. @Aspect 기반 μ–΄λ“œλ°”μ΄μ € μ €μž₯: μƒμ„±ν•œ μ–΄λ“œλ°”μ΄μ €λ₯Ό @Aspect μ–΄λ“œλ°”μ΄μ € λΉŒλ” 내뢀에 μ €μž₯

@Aspect μ–΄λ“œλ°”μ΄μ € λΉŒλ”(BeanFactoryAspectJAdvisorsBuilder)

  • @Aspect 정보λ₯Ό 기반으둜 포인트컷, μ–΄λ“œλ°”μ΄μŠ€, μ–΄λ“œλ°”μ΄μ € 생성 및 보관(캐싱)

Result
  • μžλ™ ν”„λ‘μ‹œλ₯Ό μƒμ„±κΈ°μ˜ λ™μž‘κ³Ό λ™μΌν•œλ°, @Aspect Advisor 쑰회 뢀뢄이 μΆ”κ°€

Aspect 적용 클래슀

@Aspect ν”„λ‘μ‹œ - 적용arrow-up-right

⭐️ Spring AOP

μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ‘œμ§μ€ 크게 핡심 κΈ°λŠ₯κ³Ό λΆ€κ°€ κΈ°λŠ₯으둜 λ‚˜λˆŒ 수 있음

μ—¬κΈ°μ„œ, λΆ€κ°€ κΈ°λŠ₯ 적용의 문제

  • 적용 μ‹œ λ§Žμ€ 반볡 ν•„μš”

  • μ—¬λŸ¬ 곳에 쀑볡 μ½”λ“œ λ°œμƒ

  • λ³€κ²½ μ‹œ μ€‘λ³΅μœΌλ‘œ λ§Žμ€ μˆ˜μ • ν•„μš”

  • 적용 λŒ€μƒ λ³€κ²½ μ‹œ λ§Žμ€ μˆ˜μ • ν•„μš”

Aspect

  • λΆ€κ°€ κΈ°λŠ₯κ³Ό λΆ€κ°€ κΈ°λŠ₯을 어디에 μ μš©ν• μ§€ μ„ νƒν•˜λŠ” κΈ°λŠ₯을 ν•˜λ‚˜λ‘œ ν•©ν•˜μ—¬ λ§Œλ“€μ–΄μ§„ λͺ¨λ“ˆ

    • Advisor(Pointcut + Advice) 도 κ°œλ…μƒ ν•˜λ‚˜μ˜ Aspect

  • μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ λ°”λΌλ³΄λŠ” 관점을 ν•˜λ‚˜μ˜ κΈ°λŠ₯μ—μ„œ νš‘λ‹¨ 관심사(cross-cutting concerns) κ΄€μ μœΌλ‘œ λ³΄λŠ” 것

  • Aspect λ₯Ό μ‚¬μš©ν•œ ν”„λ‘œκ·Έλž˜λ° 방식을 관점 μ§€ν–₯ ν”„λ‘œκ·Έλž˜λ° AOP(Aspect-Oriented Programming)

  • OOP λ₯Ό λŒ€μ²΄ν•˜κΈ° μœ„ν•œ 것이 μ•„λ‹Œ νš‘λ‹¨ 관심사λ₯Ό 효율적으둜 μ²˜λ¦¬ν•˜κΈ° μ–΄λ €μš΄ OOP의 λΆ€μ‘±ν•œ λΆ€λΆ„ 보쑰 λͺ©μ μœΌλ‘œ 개발

AspectJ Framework

  • μŠ€ν”„λ§ AOPλŠ” λŒ€λΆ€λΆ„ AspectJarrow-up-right 문법을 μ°¨μš©ν•˜κ³ , ν”„λ‘μ‹œ λ°©μ‹μ˜ AOP 적용(AspectJ 제곡 κΈ°λŠ₯ μΌλΆ€λ§Œ 제곡)

  • AspectJ FrameworkλŠ” νš‘λ‹¨ κ΄€μ‹¬μ‚¬μ˜ κΉ”λ”ν•œ λͺ¨λ“ˆν™”

    • μžλ°” ν”„λ‘œκ·Έλž˜λ° 언어에 λŒ€ν•œ μ™„λ²½ν•œ 관점 μ§€ν–₯ ν™•μž₯

    • νš‘λ‹¨ κ΄€μ‹¬μ‚¬μ˜ κΉ”λ”ν•œ λͺ¨λ“ˆν™”

    • 였λ₯˜ 검사 및 처리

    • 동기화

    • μ„±λŠ₯ μ΅œμ ν™”(캐싱)

    • λͺ¨λ‹ˆν„°λ§ 및 λ‘œκΉ…

AOP 적용 방식

컴파일 μ‹œμ 

Result
  • .java μ†ŒμŠ€ μ½”λ“œλ₯Ό 컴파일러(AspectJκ°€ μ œκ³΅ν•˜λŠ” νŠΉλ³„ν•œ 컴파일러)λ₯Ό μ‚¬μš©ν•΄μ„œ .class λ₯Ό λ§Œλ“œλŠ” μ‹œμ μ— λΆ€κ°€ κΈ°λŠ₯ 둜직 μΆ”κ°€ (=Weaving / aspect 와 μ‹€μ œ μ½”λ“œλ₯Ό μ—°κ²°)

  • 단점, 컴파일 μ‹œμ μ— λΆ€κ°€ κΈ°λŠ₯을 μ μš©ν•˜λ €λ©΄ νŠΉλ³„ν•œ μ»΄νŒŒμΌλŸ¬κ°€ ν•„μš”ν•˜κ³  볡작

클래슀 λ‘œλ”© μ‹œμ 

Result
  • μžλ°”λ₯Ό μ‹€ν–‰ν•˜λ©΄ μžλ°”λŠ” .class νŒŒμΌμ„ JVM λ‚΄λΆ€μ˜ 클래슀 λ‘œλ”μ— 보관. μ΄λ•Œ μ€‘κ°„μ—μ„œ .class νŒŒμΌμ„ μ‘°μž‘ν•œ λ‹€μŒ JVM에 λ‘œλ“œ

    • λŒ€λΆ€λΆ„ λͺ¨λ‹ˆν„°λ§ νˆ΄λ“€μ΄ java Instrumentation 방식 μ‚¬μš©

  • 단점, λ‘œλ“œ νƒ€μž„ μœ„λΉ™μ€ μžλ°”λ₯Ό μ‹€ν–‰ν•  λ•Œ νŠΉλ³„ν•œ μ˜΅μ…˜(java -javaagent)을 톡해 클래슀 λ‘œλ” μ‘°μž‘κΈ°λ₯Ό μ§€μ •ν•΄μ•Ό ν•˜λŠ”λ°, 이 뢀뢄이 번거둭고 운영이 어렀움

λŸ°νƒ€μž„ μ‹œμ (ν”„λ‘μ‹œ)

Result
  • λŸ°νƒ€μž„ μ‹œμ (컴파일이 λλ‚˜κ³ , 클래슀 λ‘œλ”μ— ν΄λž˜μŠ€λ„ λ‹€ μ˜¬λΌκ°€κ³ , 이미 μžλ°”κ°€ μ‹€ν–‰λ˜κ³  λ‚œ λ‹€μŒ μƒνƒœ, μžλ°”μ˜ main λ©”μ„œλ“œ μ‹€ν–‰ 이후) ν”„λ‘μ‹œλ₯Ό 톡해 μŠ€ν”„λ§ λΉˆμ— λΆ€κ°€ κΈ°λŠ₯을 적용(AOP)

  • 단점, ν”„λ‘μ‹œ μ‚¬μš©μœΌλ‘œ AOP κΈ°λŠ₯에 일뢀 μ œμ•½(final, 상속, μƒμ„±μž, ..)이 μžˆμ§€λ§Œ, λ‹€λ₯Έ λ°©λ²•μ—μ„œ λ³΅μž‘ν•œ μ„€μ • 단계가 λΆˆν•„μš”

λΆ€κ°€ κΈ°λŠ₯이 μ μš©λ˜λŠ” 차이

  • 컴파일 μ‹œμ : μ‹€μ œ λŒ€μƒ μ½”λ“œμ— μ• μŠ€νŒ©νŠΈλ₯Ό ν†΅ν•œ λΆ€κ°€ κΈ°λŠ₯ 호좜 μ½”λ“œκ°€ 포함 (AspectJ 직접 μ‚¬μš© ν•„μš”)

  • 클래슀 λ‘œλ”© μ‹œμ : μ‹€μ œ λŒ€μƒ μ½”λ“œμ— μ• μŠ€νŒ©νŠΈλ₯Ό ν†΅ν•œ λΆ€κ°€ κΈ°λŠ₯ 호좜 μ½”λ“œκ°€ 포함 (AspectJ 직접 μ‚¬μš© ν•„μš”)

  • λŸ°νƒ€μž„ μ‹œμ : μ‹€μ œ λŒ€μƒ μ½”λ“œλŠ” κ·ΈλŒ€λ‘œ μœ μ§€ν•˜λŠ” λŒ€μ‹  ν”„λ‘μ‹œλ₯Ό 톡해 λΆ€κ°€ κΈ°λŠ₯이 적용 (항상 ν”„λ‘μ‹œλ₯Ό 톡해 λΆ€κ°€ κΈ°λŠ₯ μ‚¬μš© -> μŠ€ν”„λ§ AOP μ‚¬μš© 방식)

Join Point(AOPλ₯Ό μ μš©ν•  수 μžˆλŠ” 지점)

  • AOPλŠ” λ©”μ„œλ“œ μ‹€ν–‰ μœ„μΉ˜ 뿐만 μ•„λ‹ˆλΌ, λ‹€μ–‘ν•œ μœ„μΉ˜μ— 적용 κ°€λŠ₯

    • 적용 κ°€λŠ₯ 지점: μƒμ„±μž, ν•„λ“œ κ°’ μ ‘κ·Ό, static λ©”μ„œλ“œ μ ‘κ·Ό, λ©”μ„œλ“œ μ‹€ν–‰

  • 컴파일 μ‹œμ  / 클래슀 λ‘œλ”© μ‹œμ 

    • λ°”μ΄νŠΈ μ½”λ“œλ₯Ό μ‹€μ œ μ‘°μž‘ν•˜κΈ° λ•Œλ¬Έμ— ν•΄λ‹Ή κΈ°λŠ₯을 λͺ¨λ“  지점에 λ‹€ 적용 κ°€λŠ₯

  • μŠ€ν”„λ§ AOP

    • ν”„λ‘μ‹œ 방식을 μ‚¬μš©(μ˜€λ²„λΌμ΄λ”© κ°œλ…μœΌλ‘œ λ™μž‘)ν•˜λ―€λ‘œ λ©”μ„œλ“œ μ‹€ν–‰ μ§€μ μ—λ§Œ AOP 적용 κ°€λŠ₯

    • μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆκ°€ 관리할 수 μžˆλŠ” μŠ€ν”„λ§ λΉˆμ—λ§Œ AOP 적용 κ°€λŠ₯

  • AspectJλŠ” 더 μ„¬μ„Έν•˜κ³  λ‹€μ–‘ν•œ κΈ°λŠ₯을 μ œκ³΅ν•˜μ§€λ§Œ, μ•Œμ•„μ•Ό ν•  λ‚΄μš©μ΄ 많고, μžλ°” κ΄€λ ¨ λ³΅μž‘ν•œ 섀정이 λ§ŽμœΌλ―€λ‘œ, μ‹€λ¬΄μ—μ„œλŠ” 별도 μ„€μ • 없이 μ‚¬μš©ν•  수 μžˆλŠ” μŠ€ν”„λ§ 제곡 AOP κΈ°λŠ₯만 μ‚¬μš©ν•΄λ„ λŒ€λΆ€λΆ„μ˜ 문제λ₯Ό ν•΄κ²° κ°€λŠ₯

AOP μš©μ–΄

Join point

  • AOPλ₯Ό μ μš©ν•  수 μžˆλŠ” λͺ¨λ“  지점(μœ„μΉ˜, λ©”μ†Œλ“œ μ‹€ν–‰, μƒμ„±μž 호좜, ν•„λ“œ κ°’ μ ‘κ·Ό, static λ©”μ„œλ“œ μ ‘κ·Ό)

  • ν”„λ‘μ‹œλ₯Ό μ‚¬μš©ν•˜λŠ” μŠ€ν”„λ§ AOPλŠ” 항상 λ©”μ„œλ“œ μ‹€ν–‰ μ§€μ μœΌλ‘œ μ œν•œ

Pointcut

  • Pointcut μ€‘μ—μ„œ Adviceκ°€ 적용될 μœ„μΉ˜ 선별(주둜 AspectJ ν‘œν˜„μ‹μ„ μ‚¬μš©ν•΄μ„œ μ§€μ •)

  • ν”„λ‘μ‹œλ₯Ό μ‚¬μš©ν•˜λŠ” μŠ€ν”„λ§ AOPλŠ” λ©”μ„œλ“œ μ‹€ν–‰ μ§€μ λ§Œ Pointcut으둜 선별 κ°€λŠ₯

Target

  • Advice(λΆ€κ°€ κΈ°λŠ₯)λ₯Ό λ°›λŠ” 객체, Pointcut으둜 κ²°μ •

Advice

  • λΆ€κ°€ κΈ°λŠ₯

  • Around, Before, After 같은 λ‹€μ–‘ν•œ μ’…λ₯˜μ˜ Advic 쑴재

Aspect

  • Advice + Pointcut을 λͺ¨λ“ˆν™” ν•œ 것(@Aspect)

  • μ—¬λŸ¬ Advice와 Pointcut ν•¨κ»˜ 쑴재 κ°€λŠ₯

Advisor

  • ν•˜λ‚˜μ˜ Advice와 ν•˜λ‚˜μ˜ Pointcut으둜 ꡬ성

  • μŠ€ν”„λ§ AOPμ—μ„œλ§Œ μ‚¬μš©λ˜λŠ” νŠΉλ³„ν•œ μš©μ–΄

Weaving

  • Pointcut으둜 κ²°μ •ν•œ νƒ€μΌ“μ˜ Join point에 Adviceλ₯Ό μ μš©ν•˜λŠ” 것

  • 핡심 κΈ°λŠ₯ μ½”λ“œμ— 영ν–₯을 μ£Όμ§€ μ•Šκ³  λΆ€κ°€ κΈ°λŠ₯을 μΆ”κ°€ κ°€λŠ₯

  • AOP μ μš©μ„ μœ„ν•΄ μ• μŠ€νŽ™νŠΈλ₯Ό 객체에 μ—°κ²°ν•œ μƒνƒœ

    • 컴파일 νƒ€μž„(AspectJ compiler)

    • λ‘œλ“œ νƒ€μž„

    • λŸ°νƒ€μž„, μŠ€ν”„λ§ AOPλŠ” λŸ°νƒ€μž„, ν”„λ‘μ‹œ 방식

AOP Proxy

  • AOP κΈ°λŠ₯을 κ΅¬ν˜„ν•˜κΈ° μœ„ν•΄ λ§Œλ“  ν”„λ‘μ‹œ 객체

  • μŠ€ν”„λ§μ—μ„œ AOP ν”„λ‘μ‹œλŠ” JDK 동적 ν”„λ‘μ‹œ λ˜λŠ” CGLIB ν”„λ‘μ‹œ

⭐️ AOP κ΅¬ν˜„

  • AOP κΈ°λŠ₯ μ‚¬μš©μ„ μœ„ν•΄ spring-boot-starter-aop dependency μΆ”κ°€

  • @Aspect μ‚¬μš©μ„ μœ„ν•΄ @EnableAspectJAutoProxy 섀정이 ν•„μš”ν•˜μ§€λ§Œ, μŠ€ν”„λ§ λΆ€νŠΈκ°€ μžλ™μœΌλ‘œ μΆ”κ°€

@Aspect 클래슀λ₯Ό μŠ€ν”„λ§ 빈으둜 λ“±λ‘ν•˜λŠ” 방법

  • @Bean 을 μ‚¬μš©ν•΄μ„œ 직접 등둝

  • @Component μ»΄ν¬λ„ŒνŠΈ μŠ€μΊ”μ„ μ‚¬μš©ν•΄μ„œ μžλ™ 등둝

  • @Import 주둜 μ„€μ • νŒŒμΌμ„ μΆ”κ°€ν•  λ•Œ μ‚¬μš©(@Configuration)

μŠ€ν”„λ§ AOP κ΅¬ν˜„ κΈ°λ³Έarrow-up-right

@Pointcut

Advice μˆœμ„œ

  • μ–΄λ“œλ°”μ΄μŠ€λŠ” 기본적으둜 μˆœμ„œλ₯Ό 보μž₯ν•˜μ§€ μ•ŠμŒ

  • @Order λ₯Ό μ‚¬μš©ν•  수 μžˆμ§€λ§Œ, μ–΄λ“œλ°”μ΄μŠ€ λ‹¨μœ„κ°€ μ•„λ‹ˆλΌ 클래슀 λ‹¨μœ„λ‘œ 적용 ν•„μš”

Advice μ’…λ₯˜

μ°Έκ³ .

  • JoinPoint Interface μ£Όμš” κΈ°λŠ₯

    • getArgs() : λ©”μ„œλ“œ 인수 λ°˜ν™˜

    • getThis() : ν”„λ‘μ‹œ 객체 λ°˜ν™˜

    • getTarget() : λŒ€μƒ 객체 λ°˜ν™˜

    • getSignature() : μ‘°μ–Έλ˜λŠ” λ©”μ„œλ“œμ— λŒ€ν•œ μ„€λͺ… λ°˜ν™˜

    • toString() : μ‘°μ–Έλ˜λŠ” 방법에 λŒ€ν•œ μœ μš©ν•œ μ„€λͺ… λ°˜ν™˜

  • ProceedingJoinPoint Interface μ£Όμš” κΈ°λŠ₯

    • proceed() : λ‹€μŒ μ–΄λ“œλ°”μ΄μŠ€λ‚˜ 타켓 호좜

Result
  • @Around : λ©”μ„œλ“œ 호좜 μ „/후에 μˆ˜ν–‰

    • λ‹€λ₯Έ μ–΄λ“œλ°”μ΄μŠ€ κΈ°λŠ₯ λͺ¨λ‘ 처리(쑰인 포인트 μ‹€ν–‰ μ—¬λΆ€ 선택, λ°˜ν™˜ κ°’ λ³€ν™˜, μ˜ˆμ™Έ λ³€ν™˜ λ“±)

    • λ‹€μŒ μ–΄λ“œλ°”μ΄μŠ€λ‚˜ 타켓 ν˜ΈμΆœμ„ μœ„ν•΄ ProceedingJoinPoint μ‚¬μš©ν•˜κ³ , λ‚˜λ¨Έμ§€ μ–΄λ“œλ°”μ΄μŠ€λŠ” JoinPoint μ‚¬μš©

    • 항상 joinPoint.proceed() 호좜 ν•΄μ•Ό ν•˜λŠ” 뢀뢄을 주의

  • @Before : 쑰인 포인트 μ‹€ν–‰ 전에 μ‹€ν–‰

    • μž‘μ—… 흐름 λ³€κ²½ λΆˆκ°€

    • λ©”μ„œλ“œ μ’…λ£Œ μ‹œ λ‹€μŒ 타켓(proceed()) μžλ™ 호좜

  • @After : 쑰인 ν¬μΈνŠΈκ°€ 정상 λ˜λŠ” μ˜ˆμ™Έμ— 관계없이 μ‹€ν–‰

    • λ©”μ„œλ“œ 싀행이 μ’…λ£Œλ˜λ©΄ μ‹€ν–‰(=finally)

    • 정상 및 μ˜ˆμ™Έ λ°˜ν™˜ 쑰건을 λͺ¨λ‘ 처리

    • 일반적으둜 λ¦¬μ†ŒμŠ€ ν•΄μ œμ— μ‚¬μš©

  • @AfterReturning : 쑰인 포인트 정상 μ™„λ£Œ ν›„ μ‹€ν–‰

    • returning 속성 이름은 μ–΄λ“œλ°”μ΄μŠ€ λ©”μ„œλ“œ λ§€κ°œλ³€μˆ˜ 이름 일치

    • returning μ ˆμ— μ§€μ •λœ νƒ€μž…μ˜ κ°’(Obejct)을 λ°˜ν™˜ν•˜λŠ” λ©”μ„œλ“œλ§Œ λŒ€μƒ

    • λ°˜ν™˜λ˜λŠ” 객체 λ³€κ²½ λΆˆκ°€

  • @AfterThrowing : λ©”μ„œλ“œκ°€ μ˜ˆμ™Έλ₯Ό λ˜μ§€λŠ” 경우 μ‹€ν–‰

    • @AfterReturning νŠΉμ§•κ³Ό 동일

  • @Around κ°€ κ°€μž₯ 넓은 κΈ°λŠ₯을 μ œκ³΅ν•˜μ§€λ§Œ, @Before, @After 와 같이 μ œμ•½μ΄ μžˆλŠ” μ–΄λ“œλ°”μ΄μŠ€λ₯Ό μ‚¬μš©ν•΄μ„œ λͺ…ν™•ν•˜κ²Œ 섀계λ₯Ό ν•΄λ³΄μž.

μ–΄λ“œλ°”μ΄μŠ€ μ’…λ₯˜arrow-up-right

포인트컷

Pointcut μ§€μ‹œμž

  • 포인트컷 ν‘œν˜„μ‹(AspectJ pointcut expression)은 execution 같은 포인트컷 μ§€μ‹œμž(PCD, Pointcut Designator)둜 μ‹œμž‘

  • 포인트컷 μ§€μ‹œμž μ’…λ₯˜

    • execution : λ©”μ†Œλ“œ μ‹€ν–‰ 쑰인 포인트 λ§€μΉ­(κ°€μž₯ 많이 μ‚¬μš©ν•˜κ³ , κΈ°λŠ₯도 볡작)

    • within : νŠΉμ • νƒ€μž… λ‚΄μ˜ 쑰인 포인트 λ§€μΉ­

    • args : μΈμžκ°€ μ£Όμ–΄μ§„ νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€μΈ 쑰인 포인트

    • this : μŠ€ν”„λ§ 빈 객체(μŠ€ν”„λ§ AOP ν”„λ‘μ‹œ)λ₯Ό λŒ€μƒμœΌλ‘œ ν•˜λŠ” 쑰인 포인트

    • target : Target 객체(μŠ€ν”„λ§ AOP ν”„λ‘μ‹œκ°€ κ°€λ₯΄ν‚€λŠ” μ‹€μ œ λŒ€μƒ)λ₯Ό λŒ€μƒμœΌλ‘œ ν•˜λŠ” 쑰인 포인트

    • @target : μ‹€ν–‰ 객체의 ν΄λž˜μŠ€μ— μ£Όμ–΄μ§„ νƒ€μž…μ˜ μ• λ…Έν…Œμ΄μ…˜μ΄ μžˆλŠ” 쑰인 포인트

    • @within : μ£Όμ–΄μ§„ μ• λ…Έν…Œμ΄μ…˜μ΄ μžˆλŠ” νƒ€μž… λ‚΄ 쑰인 포인트

    • @annotation : λ©”μ„œλ“œκ°€ μ£Όμ–΄μ§„ μ• λ…Έν…Œμ΄μ…˜μ„ κ°€μ§€κ³  μžˆλŠ” 쑰인 포인트λ₯Ό λ§€μΉ­

    • @args : μ „λ‹¬λœ μ‹€μ œ 인수의 λŸ°νƒ€μž„ νƒ€μž…μ΄ μ£Όμ–΄μ§„ νƒ€μž…μ˜ μ• λ…Έν…Œμ΄μ…˜μ„ κ°–λŠ” 쑰인 포인트

    • bean : μŠ€ν”„λ§ μ „μš© 포인트컷 μ§€μ‹œμž, 빈 μ΄λ¦„μœΌλ‘œ 포인트컷 μ§€μ •

execution 문법

  • execution(modifiers-pattern? ret-type-pattern declaring-type-pattern namepattern(param-pattern) throws-pattern?)

    • execution(μ ‘κ·Όμ œμ–΄μžνŒ¨ν„΄? λ°˜ν™˜νƒ€μž…νŒ¨ν„΄ μ„ μ–Ένƒ€μž…νŒ¨ν„΄? λ©”μ„œλ“œμ΄λ¦„νŒ¨ν„΄(νŒŒλΌλ―Έν„°) μ˜ˆμ™ΈνŒ¨ν„΄?)

      • λ©”μ†Œλ“œ μ‹€ν–‰ 쑰인 포인트 λ§€μΉ­

      • ?λŠ” μƒλž΅ κ°€λŠ₯ν•œ νŒ¨ν„΄

      • * νŒ¨ν„΄ μ§€μ • κ°€λŠ₯

νŒ¨ν‚€μ§€ 패칭 κ·œμΉ™

  • hello.aop.member.(1).(2)

    • (1): νƒ€μž…

    • (2): λ©”μ„œλ“œ 이름

  • . : μ •ν™•ν•˜κ²Œ ν•΄λ‹Ή μœ„μΉ˜μ˜ νŒ¨ν‚€μ§€

  • .. : ν•΄λ‹Ή μœ„μΉ˜μ˜ νŒ¨ν‚€μ§€μ™€ κ·Έ ν•˜μœ„ νŒ¨ν‚€μ§€λ„ 포함

λ©”μ„œλ“œ/νŒ¨ν‚€μ§€ 이름 λ§€μΉ­arrow-up-right

νŒŒλΌλ―Έν„° λ§€μΉ­ κ·œμΉ™

  • (String) : μ •ν™•ν•˜κ²Œ String νƒ€μž… νŒŒλΌλ―Έν„°

  • () : νŒŒλΌλ―Έν„° μ—†μŒ

  • (*) : μ •ν™•νžˆ ν•˜λ‚˜μ˜ νŒŒλΌλ―Έν„°, 단 λͺ¨λ“  νƒ€μž… ν—ˆμš©

  • (*, *) : μ •ν™•νžˆ 두 개의 νŒŒλΌλ―Έν„°, 단 λͺ¨λ“  νƒ€μž… ν—ˆμš©

  • (..) : μˆ«μžμ™€ λ¬΄κ΄€ν•˜κ²Œ λͺ¨λ“  νŒŒλΌλ―Έν„°, λͺ¨λ“  νƒ€μž… ν—ˆμš©. νŒŒλΌλ―Έν„°κ°€ 없어도 ν—ˆμš© (= 0..*)

  • (String, ..) : String νƒ€μž…μœΌλ‘œ μ‹œμž‘. μˆ«μžμ™€ λ¬΄κ΄€ν•˜κ²Œ λͺ¨λ“  νŒŒλΌλ―Έν„°, λͺ¨λ“  νƒ€μž… ν—ˆμš©

    • ex. (String) , (String, Xxx) , (String, Xxx, Xxx) ν—ˆμš©

νƒ€μž…/νŒŒλΌλ―Έν„° λ§€μΉ­arrow-up-right

within μ§€μ‹œμž

  • νŠΉμ • νƒ€μž… λ‚΄ 쑰인 ν¬μΈνŠΈμ— λŒ€ν•œ λ§€μΉ­ μ œν•œ

    • ν•΄λ‹Ή νƒ€μž…μ΄ 맀칭되면 κ·Έ μ•ˆμ˜ λ©”μ„œλ“œ(쑰인 포인트)듀이 μžλ™μœΌλ‘œ λ§€μΉ­

    • execution νƒ€μž… λΆ€λΆ„λ§Œ μ‚¬μš©

    • λΆ€λͺ¨ νƒ€μž… μ§€μ • λΆˆκ°€

    • 거의 μ‚¬μš©ν•˜μ§€ μ•Šκ³ , 보톡 execution μ‚¬μš©

within μ§€μ‹œμžarrow-up-right

args μ§€μ‹œμž

  • μΈμžκ°€ μ£Όμ–΄μ§„ νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€μΈ 쑰인 포인트둜 λ§€μΉ­

  • executionr vs args

    • executionr

      • νŒŒλΌλ―Έν„° νƒ€μž…μ˜ μ •ν™•ν•œ λ§€μΉ­

      • ν΄λž˜μŠ€μ— μ„ μ–Έλœ 정보(λ©”μ„œλ“œ μ‹œκ·Έλ‹ˆμ²˜) 기반 νŒλ‹¨ / 정적

    • args

      • λΆ€λͺ¨ νƒ€μž… ν—ˆμš©

      • μ‹€μ œ λ„˜μ–΄μ˜¨ νŒŒλΌλ―Έν„° 객체 μΈμŠ€ν„΄μŠ€(λŸ°νƒ€μž„μ— μ „λ‹¬λœ 인수) 기반 νŒλ‹¨ / 동적

      • λ‹¨λ…μœΌλ‘œ μ‚¬μš©λ˜κΈ° 보닀 νŒŒλΌλ―Έν„° 바인딩에 주둜 μ‚¬μš©

argsarrow-up-right

@target, @within μ§€μ‹œμž

νŒŒλΌλ―Έν„° 바인딩에 ν•¨κ»˜ μ‚¬μš©

  • @target : μΈμŠ€ν„΄μŠ€ κΈ°μ€€μœΌλ‘œ λͺ¨λ“  λ©”μ„œλ“œμ˜ 쑰인 포인트λ₯Ό μ„ μ •

    • λΆ€λͺ¨ νƒ€μž…μ˜ λ©”μ„œλ“œλ„ 적용

  • @within : μ„ νƒλœ 클래슀 내뢀에 μžˆλŠ” λ©”μ„œλ“œλ§Œ 쑰인 포인트둜 μ„ μ •

    • λΆ€λͺ¨ νƒ€μž…μ˜ λ©”μ„œλ“œλŠ” μ μš©λ˜μ§€ μ•ŠμŒ

@target, @withinarrow-up-right

μ°Έκ³ . args, @args, @target μ§€μ‹œμžλŠ” λ‹¨λ…μœΌλ‘œ μ‚¬μš©ν•˜μ§€ μ•ŠκΈ° !!!

  • μ‹€μ œ 객체 μΈμŠ€ν„΄μŠ€κ°€ 생성, 싀행될 λ•Œ μ–΄λ“œλ°”μ΄μŠ€ 적용 μ—¬λΆ€λ₯Ό 확인 κ°€λŠ₯ν•˜λ―€λ‘œ ν”„λ‘μ‹œκ°€ μžˆμ–΄μ•Όλ§Œ(μ‹€ν–‰ μ‹œμ ) νŒλ‹¨ κ°€λŠ₯

  • 단, ν”„λ‘μ‹œλ₯Ό μƒμ„±ν•˜λŠ” μ‹œμ μ€ μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆκ°€ λ§Œλ“€μ–΄μ§€λŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ‘œλ”© μ‹œμ μ΄λ―€λ‘œ args, @args, @target μ§€μ‹œμžλŠ” μŠ€ν”„λ§μ˜ λͺ¨λ“  λΉˆμ— AOPλ₯Ό μ μš©ν•˜λ €κ³  μ‹œλ„ -> μŠ€ν”„λ§ λ‚΄λΆ€μ—μ„œ μ‚¬μš©ν•˜λŠ” 빈 μ€‘μ—λŠ” final μ§€μ • λΉˆλ“€λ„ 있기 λ•Œλ¬Έμ— 였λ₯˜ λ°œμƒ

  • μ΅œλŒ€ν•œ ν”„λ‘μ‹œ 적용 λŒ€μƒμ„ μΆ•μ†Œν•˜λŠ” ν‘œν˜„μ‹(execution)κ³Ό ν•¨κ»˜ μ‚¬μš©ν•˜κΈ°

@annotation, @args μ§€μ‹œμž

  • @annotation : μ£Όμ–΄μ§„ μ• λ…Έν…Œμ΄μ…˜(@MethodAop)을 κ°€μ§€κ³  μžˆλŠ” λ©”μ„œλ“œλ₯Ό 쑰인 포인트 λ§€μΉ­

  • @args : λŸ°νƒ€μž„ νƒ€μž…μ— μ „λ‹¬λœ μΈμˆ˜κ°€ μ£Όμ–΄μ§„ νƒ€μž…μ˜(@Check) μ• λ…Έν…Œμ΄μ…˜μ΄ μžˆλŠ” κ²½μš°μ— λ§€μΉ­

@annotation, @argsarrow-up-right

bean μ§€μ‹œμž

  • 빈 μ΄λ¦„μœΌλ‘œ AOP 적용 μ—¬λΆ€ μ§€μ •(μŠ€ν”„λ§ μ „μš© 포인트컷 μ§€μ‹œμž)

beanarrow-up-right

this, target μ§€μ‹œμž

  • this : μŠ€ν”„λ§ 빈으둜 λ“±λ‘λ˜μ–΄ μžˆλŠ” ν”„λ‘μ‹œ 객체λ₯Ό λŒ€μƒμœΌλ‘œ 포인트컷 λ§€μΉ­

  • target : μŠ€ν”„λ§ AOP ν”„λ‘μ‹œ 객체가 κ°€λ₯΄ν‚€λŠ” μ‹€μ œ target 객체λ₯Ό λŒ€μƒμœΌλ‘œ 포인트컷 λ§€μΉ­

    • ν”„λ‘μ‹œ λŒ€μƒμΈ this λŠ” ꡬ체 클래슀 μ§€μ • μ‹œ ν”„λ‘μ‹œ 생성 μ „λž΅μ— 따라 λ‹€λ₯Έ κ²°κ³Όκ°€ λ‚˜μ˜¬ 수 있음

        • 와 같은 νŒ¨ν„΄ μ‚¬μš© λΆˆκ°€

      • λΆ€λͺ¨ νƒ€μž… ν—ˆμš©

    • λ‹¨λ…μœΌλ‘œ μ‚¬μš©λ˜κΈ° λ³΄λ‹€λŠ” νŒŒλΌλ―Έν„° 바인딩에 주둜 μ‚¬μš©

this vs targetarrow-up-right

λ§€κ°œλ³€μˆ˜ 전달

  • 포인트컷 ν‘œν˜„μ‹μ„ μ‚¬μš©ν•΄μ„œ μ–΄λ“œλ°”μ΄μŠ€μ— λ§€κ°œλ³€μˆ˜ 전달 κ°€λŠ₯

    • this, target, args,@target, @within, @annotation, @args

    • λ©”μ„œλ“œμ— μ§€μ •ν•œ νƒ€μž…μœΌλ‘œ μ œν•œ

λ§€κ°œλ³€μˆ˜ 전달arrow-up-right

⭐️ AOP μ‹€μ „μ˜ˆμ œ

μ°Έκ³ . μŠ€ν”„λ§μ˜ κ°€μž₯ λŒ€ν‘œμ μΈ AOPλŠ” @Transactional

⭐️ μ£Όμ˜μ‚¬ν•­

ν”„λ‘μ‹œ λ°©μ‹μ˜ AOP ν•œκ³„ - λŒ€μƒ 객체λ₯Ό 직접 호좜

  • μ˜μ‘΄κ΄€κ³„ μ£Όμž… μ‹œ ν”„λ‘μ‹œ 객체가 μ£Όμž…λ˜λ―€λ‘œ λŒ€μƒ 객체λ₯Ό 직접 ν˜ΈμΆœν•˜λŠ” λ¬Έμ œλŠ” 일반적으둜 λ°œμƒν•˜μ§€ μ•Šμ§€λ§Œ, λŒ€μƒ 객체의 λ‚΄λΆ€μ—μ„œ λ©”μ„œλ“œ 호좜(μžμ‹ μ˜ μΈμŠ€ν„΄μŠ€ λ‚΄λΆ€ λ©”μ„œλ“œ 호좜)이 λ°œμƒν•˜λ©΄ ν”„λ‘μ‹œλ₯Ό κ±°μΉ˜μ§€ μ•Šκ³  λŒ€μƒ 객체λ₯Ό 직접 ν˜ΈμΆœν•˜λŠ” 문제 λ°œμƒ

  • μŠ€ν”„λ§μ€ ν”„λ‘μ‹œ λ°©μ‹μ˜ AOPλ₯Ό μ‚¬μš©ν•˜λŠ”λ°, λ©”μ„œλ“œ λ‚΄λΆ€ ν˜ΈμΆœμ— ν”„λ‘μ‹œλ₯Ό μ μš©ν•  수 μ—†μŒ

Result
Result

ν”„λ‘μ‹œ λ°©μ‹μ˜ AOP ν•œκ³„ - ν”„λ‘μ‹œ λ°©μ‹μ˜ AOP의 λ‚΄λΆ€ 호좜 문제arrow-up-right

ν”„λ‘μ‹œ λ°©μ‹μ˜ AOP ν•œκ³„. λŒ€μ•ˆ I. 자기 μžμ‹  μ£Όμž…

  • μžμ‹ μ˜ μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λŠ” 것이 μ•„λ‹ˆλΌ, ν”„λ‘μ‹œ μΈμŠ€ν„΄μŠ€λ₯Ό ν†΅ν•΄μ„œ 호좜

λŒ€μ•ˆ I. 자기 μžμ‹  μ£Όμž…arrow-up-right

ν”„λ‘μ‹œ λ°©μ‹μ˜ AOP ν•œκ³„. λŒ€μ•ˆ II. μ§€μ—° 쑰회

  • ObjectProvider(Provider), ApplicationContext μ‚¬μš©

    • ObjectProvider : 객체 쑰회λ₯Ό μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆ μŠ€ν”„λ§ 빈 생성 μ‹œμ μ—μ„œ μ‹€μ œ 객체 μ‚¬μš© μ‹œμ (.getObject())으둜 μ§€μ—°

λŒ€μ•ˆ II. μ§€μ—° 쑰회arrow-up-right

ν”„λ‘μ‹œ λ°©μ‹μ˜ AOP ν•œκ³„. λŒ€μ•ˆ III. ꡬ쑰 λ³€κ²½

  • λ‚΄λΆ€ ν˜ΈμΆœμ„ 별도 클래슀둜 뢄리

Result

λŒ€μ•ˆ III. ꡬ쑰 λ³€κ²½arrow-up-right

ν”„λ‘μ‹œ 기술의 ν•œκ³„

νƒ€μž… μΊμŠ€νŒ…

ν”„λ‘μ‹œ μΊμŠ€νŒ… λ¬Έμ œλŠ” μ˜μ‘΄κ΄€κ³„ μ£Όμž… μ‹œ λ°œμƒ

  • JDK 동적 ν”„λ‘μ‹œ : μΈν„°νŽ˜μ΄μŠ€ 기반 ν”„λ‘μ‹œ 생성

    • ν”„λ‘μ‹œλ₯Ό μΈν„°νŽ˜μ΄μŠ€λ‘œ μΊμŠ€νŒ… κ°€λŠ₯ν•˜μ§€λ§Œ, ꡬ체 클래슀둜 νƒ€μž… μΊμŠ€νŒ…μ΄ λΆˆκ°€λŠ₯(μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ ν”„λ‘μ‹œμ΄λ―€λ‘œ..)

  • CGLIB : ꡬ체 클래슀 기반 ν”„λ‘μ‹œ 생성

    • ꡬ체 클래슀 기반으둜 ν”„λ‘μ‹œκ°€ μƒμ„±λ˜λ―€λ‘œ, ꡬ체 클래슀둜 νƒ€μž… μΊμŠ€νŒ… κ°€λŠ₯

ν”„λ‘μ‹œ 기술의 ν•œκ³„ - νƒ€μž… μΊμŠ€νŒ…arrow-up-right

μ˜μ‘΄κ΄€κ³„ μ£Όμž…

JDK 동적 ν”„λ‘μ‹œ

  • μΈν„°νŽ˜μ΄μŠ€ 기반으둜 ν”„λ‘μ‹œλ₯Ό μƒμ„±ν•΄μ„œ λŒ€μƒ 객체 Impl νƒ€μž…μ— μ˜μ‘΄κ΄€κ³„ μ£Όμž… λΆˆκ°€

Result

CGLIB

  • ꡬ체 클래슀 기반으둜 ν”„λ‘μ‹œλ₯Ό μƒμ„±ν•΄μ„œ λŒ€μƒ 객체 Impl νƒ€μž…μ— μ˜μ‘΄κ΄€κ³„ μ£Όμž… κ°€λŠ₯

Result

ν”„λ‘μ‹œ 기술과 ν•œκ³„ - μ˜μ‘΄κ΄€κ³„ μ£Όμž…arrow-up-right

CGLIB ν”„λ‘μ‹œ 문제점

  • λŒ€μƒ ν΄λž˜μŠ€μ— κΈ°λ³Έ μƒμ„±μž ν•„μˆ˜

  • μƒμ„±μžλ₯Ό 2번 호좜

    • μ‹€μ œ target 객체 생성

    • ν”„λ‘μ‹œ 객체 생성 μ‹œ λΆ€λͺ¨ 클래슀 μƒμ„±μž 호좜

  • final ν‚€μ›Œλ“œ 클래슀, λ©”μ„œλ“œ μ‚¬μš© λΆˆκ°€

μŠ€ν”„λ§μ˜ ν”„λ‘μ‹œ 기술의 ν•œκ³„ ν•΄κ²°μ±…

  • μŠ€ν”„λ§ 3.2 : CGLIBλ₯Ό μŠ€ν”„λ§ 내뢀에 ν•¨κ»˜ νŒ¨ν‚€μ§•

  • μŠ€ν”„λ§ 4.0 : objenesis 라이브러리λ₯Ό μ‚¬μš©ν•΄μ„œ κΈ°λ³Έ μƒμ„±μž ν•„μˆ˜ 문제, μƒμ„±μž 2번 호좜 문제 ν•΄κ²°

  • μŠ€ν”„λ§ λΆ€νŠΈ 2.0 : CGLIB κΈ°λ³Έ μ‚¬μš©

Last updated