Spring Framework: Spring AOP

IToriginalΒ·2023λ…„ 6μ›” 5일
0

남정넀듀: Web Study

λͺ©λ‘ 보기
5/7
post-thumbnail
post-custom-banner
μ΄μ „ν¬μŠ€νŠΈμ—μ„œ μŠ€ν”„λ§μ— λŒ€ν•΄μ„œ 쑰금 μ•Œμ•„λ³΄μ•˜λŠ”λ°, μŠ€ν”„λ§μ˜ 핡심인 IoC/DI에 λŒ€ν•΄ 이야기λ₯Ό 마쳀고, μΆ”κ°€λ‘œ AOP에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄λ €ν•œλ‹€.

μœ„μ˜ μ΄λ―Έμ§€λŠ” 이전 ν¬μŠ€νŠΈμ—μ„œ μ–ΈκΈ‰ν•œ μŠ€ν”„λ§ λͺ¨λ“ˆ μ‚¬μ΄μ˜ μƒν˜Έ 의쑴 관계λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 관계도이닀. λͺ¨λ“  λͺ¨λ“ˆμ΄ 핡심 μ»¨ν…Œμ΄λ„ˆλ₯Ό μ˜μ‘΄ν•˜λŠ” 것을 확인할 수 μžˆμ—ˆκ³ , κ·Έλž˜μ„œ μŠ€ν”„λ§μ˜ 핡심 λͺ¨λ“ˆλ‘œ μ†Œκ°œν–ˆλ‹€. ν•˜μ§€λ§Œ, λ°”λ‘œ μ˜†μ˜ AOP의 의쑴 관계도λ₯Ό μ‚΄νŽ΄λ³΄λ©΄ 핡심 μ»¨ν…Œμ΄λ„ˆλ§ŒνΌμ΄λ‚˜ μ€‘μš”ν•˜λ‹€λŠ” 것을 μ•Œ 수 μžˆμ—ˆλ‹€.

AOPκ°€ 뭘까?

μŠ€ν”„λ§μ€ λ‚΄λΆ€μ—μ„œ νŠΈλžœμž­μ…˜ 관리, 캐싱, λ³΄μ•ˆ λ“±μ˜ 선언적인 μ„œλΉ„μŠ€λ₯Ό κ΅¬ν˜„ν•˜κΈ° μœ„ν•΄ AOP ν”„λ ˆμž„μ›Œν¬λ₯Ό μ œκ³΅ν•œλ‹€.
AOP(Aspect Oriented Programming)λŠ” ν•œκΈ€λ‘œ "관점 지ν–₯ ν”„λ‘œκ·Έλž˜λ°" 라고 λΆ€λ₯΄κ³  μ—¬λŸ¬ ν΄λž˜μŠ€μ— λ‚˜λ‰œ μ±…μž„μ„ Aspect(관점)이라 λΆ€λ₯΄λŠ” λ³„λ„μ˜ ν΄λž˜μŠ€μ— μΊ‘μŠν™”ν•˜λŠ” μ ‘κ·Ό 방식을 λ§ν•œλ‹€.

그리고, μ—¬λŸ¬ ν΄λž˜μŠ€μ— 걸쳐 μžˆλŠ” μ±…μž„μ€ Cross-Cutting Concern(νš‘λ‹¨ 관심사) 라고 λΆ€λ₯Έλ‹€. (νš‘λ‹¨ κ΄€μ‹¬μ‚¬μ˜ 예: λ‘œκΉ…(logging), νŠΈλžœμž­μ…˜ 관리, 캐싱, λ³΄μ•ˆ λ“±)

νš‘λ‹¨ 관심사??

ν•„μžλŠ” AOP에 λŒ€ν•΄ μ•Œμ•„λ³΄λ € ν–ˆλŠ”λ° νš‘λ‹¨ κ΄€μ‹¬μ‚¬λΌλŠ” μ΄μƒν•˜κ³  이해가지 μ•ŠλŠ” λ‹¨μ–΄λ‘œ μ œλ™μ„ κ±Έμ–΄μ™”λ‹€.
νš‘λ‹¨ κ΄€μ‹¬μ‚¬μ˜ 예둜 λ‘œκΉ…, νŠΈλžœμ μ…˜ 관리, λ³΄μ•ˆ λ“±μ΄μžˆλ‹€κ³  ν–ˆλŠ”λ° μ΄λŸ¬ν•œ λ‹€μˆ˜μ˜ λͺ¨λ“ˆμ—μ„œ 반볡적으둜 λ‚˜νƒ€λ‚˜λŠ” 뢀뢄이 μ‘΄μž¬ν•œλ‹€.
이 반볡적인 뢀뢄을 νš‘λ‹¨ 관심이라 ν•˜λŠ”λ°, '반볡적' μ΄λΌλŠ” 단어λ₯Ό κΈ°μ–΅ν•˜κ³  μ•„λž˜μ˜ μ„€λͺ…을 보자.

μœ„μ˜ 그림을 보고 이해가 κ°€μ‹ λ‹€λ©΄, 이에 λŒ€ν•΄ 이미 μ•Œκ³  μžˆκ±°λ‚˜ Spring에 λŒ€ν•΄ μ§μž‘μ€ ν•˜λŠ” μˆ˜μ€€μΌ 것 κ°™λ‹€.
ν•„μžλŠ” 이 그림을 보고 μ²˜μŒμ— μ΄ν•΄ν•˜μ§€ λͺ»ν–ˆλ‹€.

μœ„μ˜ 그림을 보면 μž…κΈˆ, 좜금, 이체 λΆ€λΆ„μ—μ„œ λ‘œκΉ…, λ³΄μ•ˆ, νŠΈλžœμž­μ…˜κ³Ό 같이 쀑볡 코딩이 μΌμ–΄λ‚˜λŠ” 뢀뢄을 νš‘λ‹¨κ΄€μ‹¬μ΄λΌ μ΄ν•΄ν•˜λ©΄ 쒋을 것 κ°™λ‹€.

μ‰½κ²Œ 예λ₯Ό 듀어보기 μœ„ν•΄ μ–΄λŠ λ‚¨μžμ™€ μ—¬μžμ˜ ν•˜λ£¨λ₯Ό 톡해 예λ₯Ό 듀어보겠닀.

// λ‚¨μž1호의 ν•˜λ£¨
문을 μ—΄κ³  집에 λ“€μ–΄κ°„λ‹€.
μ»΄ν“¨ν„°λ‘œ κ²Œμž„μ„ ν•œλ‹€.
μ†Œλ“±ν•˜κ³  μž”λ‹€.
문을 잠그고 집을 λ‚˜μ„ λ‹€.

! μ˜ˆμ™Έ: 집에 λΆˆμ΄λ‚œλ‹€ - 119에 μ‹ κ³ ν•œλ‹€.
// μ—¬μž1호의 ν•˜λ£¨
문을 μ—΄κ³  집에 λ“€μ–΄κ°„λ‹€.
μ»΄ν“¨ν„°λ‘œ μ˜ν™”λ₯Ό λ³Έλ‹€
μ†Œλ“±ν•˜κ³  μž”λ‹€.
문을 잠그고 집을 λ‚˜μ„ λ‹€.

! μ˜ˆμ™Έ: 집에 λΆˆμ΄λ‚œλ‹€ - 119에 μ‹ κ³ ν•œλ‹€.

λ‚¨μžμ™€ μ—¬μžμ˜ ν•˜λ£¨λ₯Ό λ³΄μ•˜μ„ λ•Œ, μ–΄λ–€ 뢀뢄이 μ€‘λ³΅μœΌλ‘œ λ‚˜νƒ€λ‚˜λŠ” νš‘λ‹¨κ΄€μ‹¬μ‚¬ν•­μΈμ§€ μ•Œ 수 μžˆμ„ 것이닀.
μœ„μ˜ μ½”λ“œμ—μ„œ λΉ¨κ°„ λ°•μŠ€μ˜ 뢀뢄이 νš‘λ‹¨κ΄€μ‹¬μ‚¬ν•­μ΄ 되고 νŒŒλž€ λ°•μŠ€μ˜ 뢀뢄은 핡심관심사항이라고 ν•˜λŠ”λ° 핡심관심사항은 λͺ¨λ“ˆλ³„λ‘œ λ‹€λ₯΄μ§€λ§Œ λͺ¨λ“ˆλ³„λ‘œ 쀑볡 코딩이 μΌμ–΄λ‚˜λŠ” 뢀뢄을 λ§ν•œλ‹€.

많이 λ³΅μž‘ν•˜μ§€λ§Œ, μŠ€ν”„λ§ DIκ°€ μ˜μ‘΄μ„±(new)에 λŒ€ν•œ μ£Όμž…μ΄λΌλ©΄, AOPλŠ” 둜직(code)에 λŒ€ν•œ μ£Όμž…μ΄λΌκ³  보면 μ΄ν•΄ν•˜κΈ° μˆ˜μ›”ν•  것 κ°™λ‹€.

μœ„μ˜ μ½”λ“œμ™€ μ΄λ―Έμ§€μ²˜λŸΌ νš‘λ‹¨κ΄€μ‹¬μ‚¬ν•­μ„ Aspect둜 λͺ¨λ“ˆν™”ν•˜κ³  핡심적인 λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ—μ„œ λΆ„λ¦¬ν•˜μ—¬ μž¬μ‚¬μš©ν•˜κ² λ‹€λŠ” 것이 AOP의 취지인 것이닀.

AOP μ£Όμš” μš©μ–΄

βœ… 관점(Aspect)

  • AOP의 κΈ°λ³Έ λͺ¨λ“ˆλ‘œ 싱글톀 ν˜•νƒœμ˜ 객체둜 μ‘΄μž¬ν•œλ‹€.
  • μ—¬λŸ¬ 객체에 κ³΅ν†΅μœΌλ‘œ μ μš©λ˜λŠ” κΈ°λŠ₯ (곡톡 κΈ°λŠ₯)
  • μ–΄λ“œλ°”μ΄μŠ€(Advice) + 포인트 μ»·(Point Cut)을 λͺ¨λ“ˆν™”ν•˜μ—¬ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— ν¬ν•¨λ˜λŠ” νš‘λ‹¨ κΈ°λŠ₯(Cross-cutting Concerns)을 λ§ν•œλ‹€.
  • μ—¬λŸ¬ 개의 μ–΄λ“œλ°”μ΄μŠ€μ™€ 포인트 컷이 μ‘΄μž¬ν•œλ‹€.

Advice + PointCut = Aspect

βœ… μ–΄λ“œλ°”μ΄μŠ€(Advice)

  • μ–΄λ“œλ°”μ΄μŠ€λŠ” νƒ€κ²Ÿμ— μ œκ³΅ν•  λΆ€κ°€κΈ°λŠ₯을 λ‹΄κ³  μžˆλŠ” λͺ¨λ“ˆ
  • Sping AOPμ—μ„œλ§Œ μ‚¬μš©λ˜λŠ” νŠΉλ³„ν•œ μš©μ–΄μ΄λ‹€.
  • Advice의 μ’…λ₯˜

    μ’…λ₯˜Content
    Aroundνƒ€κ²Ÿμ˜ λ©”μ„œλ“œκ°€ 호좜되기 이전(before) μ‹œμ κ³Ό 이후(after)μ‹œμ μ— λͺ¨λ‘ μ²˜λ¦¬ν•΄μ•Ό ν•  ν•„μš”κ°€ μžˆλŠ” λΆ€κ°€ κΈ°λŠ₯을 μ •μ˜ν•œλ‹€.
    πŸš€ Joinpoint μ•žκ³Ό λ’€μ—μ„œ μ‹€ν–‰λ˜λŠ” Advice
    Beforeνƒ€κ²Ÿμ˜ λ©”μ„œλ“œκ°€ μ‹€ν–‰λ˜κΈ° 이전(before) μ‹œμ μ— μ²˜λ¦¬ν•΄μ•Ό ν•  ν•„μš”κ°€ μžˆλŠ” λΆ€κ°€κΈ°λŠ₯을 μ •μ˜ν•œλ‹€.
    πŸš€ Jointpoint μ•žμ—μ„œ μ‹€ν–‰λ˜λŠ” Advice
    After Returningνƒ€κ²Ÿμ˜ λ©”μ„œλ“œκ°€ μ •μƒμ μœΌλ‘œ μ‹€ν–‰λœ 이후(after) μ‹œμ μ— μ²˜λ¦¬ν•΄μ•Ό ν•  ν•„μš”κ°€ μžˆλŠ” λΆ€κ°€κΈ°λŠ₯을 μ •μ˜ν•œλ‹€.
    πŸš€ Jointpoint λ©”μ„œλ“œ 호좜이 μ •μƒμ μœΌλ‘œ μ’…λ£Œλœ 뒀에 μ‹€ν–‰λ˜λŠ” Advice
    After Throwingνƒ€κ²Ÿμ˜ λ©”μ„œλ“œκ°€ μ˜ˆμ™Έλ₯Ό λ°œμƒλœ 이후(after) μ‹œμ μ— μ²˜λ¦¬ν•΄μ•Ό ν•  ν•„μš”κ°€ μžˆλŠ” λΆ€κ°€κΈ°λŠ₯을 μ •μ˜ν•œλ‹€.
    πŸš€ μ˜ˆμ™Έκ°€ 던져질 λ•Œ μ‹€ν–‰λ˜λŠ” Advice

βœ… νƒ€κ²Ÿ(Target)

  • 핡심 κΈ°λŠ₯을 λ‹΄κ³  μžˆλŠ” λͺ¨λ“ˆλ‘œ νƒ€κ²Ÿμ€ λΆ€κ°€κΈ°λŠ₯을 λΆ€μ—¬ν•  λŒ€μƒμ΄ λœλ‹€.

βœ… 포인트 μ»·(PointCut)

  • μ–΄λ“œλ°”μ΄μŠ€λ₯Ό μ μš©ν•  νƒ€κ²Ÿ λ©”μ„œλ“œλ₯Ό μ„ λ³„ν•˜λŠ” μ •κ·œν‘œν˜„μ‹μ΄λ‹€.
  • 포인트 μ»· ν‘œν˜„μ‹μ€ execution으둜 μ‹œμž‘ν•˜κ³  λ©”μ„œλ“œμ˜ Signatureλ₯Ό λΉ„κ΅ν•˜λŠ” 방법을 주둜 μ΄μš©ν•œλ‹€.

βœ… μœ„λΉ™(Weaving)

  • μœ„λΉ™μ€ 포인트 컷에 μ˜ν•΄μ„œ κ²°μ •λœ νƒ€κ²Ÿμ˜ 쑰인 ν¬μΈνŠΈμ— μ–΄λ“œλ°”μ΄μŠ€(λΆ€κ°€κΈ°λŠ₯)λ₯Ό μ‚½μž…ν•˜λŠ” 과정을 λœ»ν•œλ‹€.
  • μœ„λΉ™μ€ AOPκ°€ νƒ€κ²Ÿ(핡심 κΈ°λŠ₯)의 μ½”λ“œμ— 영ν–₯을 주지 μ•ŠμœΌλ©° ν•„μš”ν•œ μ–΄λ“œλ°”μ΄μŠ€λ₯Ό μΆ”κ°€ν•  수 μžˆλ„λ‘ ν•˜λŠ” 핡심적인 처리 과정을 λ§ν•œλ‹€.

βœ… 쑰인포인트(Joinpoint)

  • μ–΄λ“œλ°”μ΄μŠ€κ°€ 적용될 수 μžˆλŠ” μœ„μΉ˜λ₯Ό λ§ν•œλ‹€.
  • νƒ€κ²Ÿ 객체가 κ΅¬ν˜„ν•œ μΈν„°νŽ˜μ΄μŠ€μ˜ λͺ¨λ“  λ©”μ„œλ“œλŠ” 쑰인 ν¬μΈνŠΈκ°€ λœλ‹€.
  • Spring AOP ν˜Ήμ€ AspectJμ—μ„œ AOPκ°€ μ μš©λ˜λŠ” 지점을 λœ»ν•˜κ³  ν•΄λ‹Ή 지점을 AspectJμ—μ„œ JoinPointλΌλŠ” μΈν„°νŽ˜μ΄μŠ€λ‘œ λ‚˜νƒ€λ‚Έλ‹€.
  • JoinPoint λ©”μ„œλ“œ

    MethodContent
    getArgs()λ©”μ„œλ“œ μ•„κ·œλ¨ΌνŠΈλ₯Ό λ°˜ν™˜ν•œλ‹€.
    getThis()ν”„λ‘μ‹œ 객체λ₯Ό λ°˜ν™˜ν•œλ‹€.
    getTarget()λŒ€μƒ 객체λ₯Ό λ°˜ν™˜ν•œλ‹€.
    getSignature()μ–΄λ“œλ°”μ΄μ¦ˆ λ˜λŠ” λ©”μ„œλ“œμ˜ μ„€λͺ…(description)을 λ°˜ν™˜ν•œλ‹€.
    toString()μ–΄λ“œλ°”μ΄μ¦ˆ λ˜λŠ” λ©”μ„œλ“œμ˜ μ„€λͺ…을 좜λ ₯ν•œλ‹€.

Proxy-based

μŠ€ν”„λ§ AOP ν”„λ ˆμž„μ›Œν¬λŠ” ν”„λ‘μ‹œ 기반(Proxy-based)이닀. ν”„λ‘μ‹œλŠ” AOP ν”„λ ˆμž„μ›Œν¬μ— μ˜ν•΄ ν˜ΈμΆœν•˜λŠ” 객체와 λŒ€μƒ 객체 사이에 λ„μž…λ˜λŠ” 쀑간 객체닀.

μŠ€ν”„λ§ AOPμ—μ„œ λŒ€μƒ κ°μ²΄λŠ” μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆμ— λ“±λ‘λœ 빈 μΈμŠ€ν„΄μŠ€μ΄λ‹€.

μ•„λž˜μ˜ λ‹€μ΄μ–΄κ·Έλž¨μ€ 은행 μ„œλΉ„μŠ€λ₯Ό 톡해 λ‘œκΉ… Aspect의 logλ©”μ„œλ“œλ₯Ό μ„œλΉ„μŠ€ 객체에 μ–΄λ–»κ²Œ μ μš©ν–ˆλŠ”μ§€λ₯Ό 보여쀀닀.

μ‹€ν–‰ μ‹œμ μ—μ„œ ν”„λ‘μ‹œλŠ” λŒ€μƒ 객체 ν˜ΈμΆœμ„ κ°€λ‘œμ±„κ³  λŒ€μƒ λ©”μ„œλ“œμ— μ μš©ν•  μ–΄λ“œλ°”μ΄μŠ€λ₯Ό μ‹€ν–‰ν•œλ‹€.
이 λ‹€μ΄μ–΄κ·Έλž¨μ€ BankAccountService(μ€ν–‰κ³„μ’Œμ„œλΉ„μŠ€)와 FixedDepositService(μ •κΈ°μ˜ˆκΈˆμ„œλΉ„μŠ€) 객체에 λŒ€ν•œ ν”„λ‘μ‹œκ°€ μƒμ„±λ˜μ–΄ 각 λ©”μ„œλ“œ(μ—¬κΈ°μ„œλŠ” create~~) ν˜ΈμΆœμ„ κ°€λ‘œμ±ˆλ‹€.

Proxy 생성

μŠ€ν”„λ§ AOPλ₯Ό μ‚¬μš©ν•  λ•ŒλŠ” μŠ€ν”„λ§μ˜ ProxyFactoryBean을 μ‚¬μš©ν•΄ ν”„λ‘μ‹œλ₯Ό λͺ…μ‹œμ μœΌλ‘œ μ‚¬μš©ν•  수 있고, μŠ€ν”„λ§μ΄ AOP ν”„λ‘μ‹œλ₯Ό μžλ™μœΌλ‘œ μƒμ„±ν•˜κ²Œ λ§Œλ“€ μˆ˜λ„ μžˆλ‹€. AOP ν”„λ‘μ‹œλ₯Ό μŠ€ν”„λ§ AOPκ°€ μžλ™μœΌλ‘œ μƒμ„±ν•˜λŠ” 경우λ₯Ό μžλ™ ν”„λ‘μ‹œ 생성(AutoProxying)이라고 ν•œλ‹€.

μŠ€ν”„λ§ AOP ν”„λ ˆμž„μ›Œν¬λŠ” JavaSEλ‚˜ CGLIB을 기반으둜 ν”„λ‘μ‹œλ₯Ό μƒμ„±ν•œλ‹€.
λŒ€μƒ 객체가 아무 μΈν„°νŽ˜μ΄μŠ€μ—λ„ κ΅¬ν˜„ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ μŠ€ν”„λ§ AOPλŠ” CGLIB기반 ν”„λ‘μ‹œλ₯Ό μƒμ„±ν•˜κ³  λŒ€μƒ 객체가 ν•˜λ‚˜ μ΄μƒμ˜ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œλ‹€λ©΄ JavaSE 기반의 ν”„λ‘μ‹œλ₯Ό μƒμ„±ν•˜κ²Œ λœλ‹€.

βœ… JavaSE: JavaSEλŠ” μžλ°” ν‘œμ€€ 라이브러리의 μΌλΆ€λ‘œ μ œκ³΅λ˜λŠ” 동적 ν”„λ‘μ‹œ 생성 κΈ°λŠ₯이닀. JavaSE 기반의 ν”„λ‘μ‹œλŠ” λŒ€μƒ 객체가 ν•˜λ‚˜ μ΄μƒμ˜ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•  λ•Œ μƒμ„±λœλ‹€. μ΄λŠ” λŒ€μƒ 객체의 μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ”°λ₯΄λŠ” ν”„λ‘μ‹œλ₯Ό μƒμ„±ν•˜μ—¬ λŒ€μƒ 객체와 ν΄λΌμ΄μ–ΈνŠΈ 사이에 μ€‘κ°œ 역할을 μˆ˜ν–‰ν•œλ‹€.
βœ… CGLIB: Code Generation Library의 μ•½μžλ‘œ, μŠ€ν”„λ§ AOPμ—μ„œ ν”„λ‘μ‹œλ₯Ό μƒμ„±ν•˜λŠ” 데 μ‚¬μš©λ˜λŠ” λΌμ΄λΈŒλŸ¬λ¦¬μ΄λ‹€. λŒ€μƒ 객체가 μ–΄λ– ν•œ μΈν„°νŽ˜μ΄μŠ€λ„ κ΅¬ν˜„ν•˜μ§€ μ•Šμ„ 경우, μŠ€ν”„λ§ AOPλŠ” CGLIB 기반의 ν”„λ‘μ‹œλ₯Ό μƒμ„±ν•œλ‹€. CGLIBλŠ” 상속을 톡해 ν”„λ‘μ‹œ 객체λ₯Ό μƒμ„±ν•˜κΈ° λ•Œλ¬Έμ— λŒ€μƒ 객체의 ν•˜μœ„ 클래슀λ₯Ό μƒμ„±ν•˜κ³ , ν”„λ‘μ‹œ κ°μ²΄λŠ” λŒ€μƒ 객체의 κΈ°λŠ₯을 μƒμ†λ°›μ•„μ„œ μ‚¬μš©ν•œλ‹€.
πŸš€ κ°„λ‹¨νžˆ λ§ν•˜λ©΄, JavaSE 기반의 ν”„λ‘μ‹œλŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό 기반으둜 λ™μž‘ν•˜λ©°, CGLIB 기반의 ν”„λ‘μ‹œλŠ” μΈν„°νŽ˜μ΄μŠ€ 없이도 λ™μž‘ν•  수 μžˆλ‹€. μŠ€ν”„λ§ AOPλŠ” λŒ€μƒ 객체의 νŠΉμ„±μ— 따라 μ μ ˆν•œ ν”„λ‘μ‹œλ₯Ό μ„ νƒν•˜μ—¬ μƒμ„±ν•œλ‹€.

Reference

πŸ“š λ°°μ›Œμ„œ λ°”λ‘œ μ“°λŠ” μŠ€ν”„λ§ ν”„λ ˆμž„μ›Œν¬
πŸ‘¨πŸ»β€πŸ’» μ—¬λ¦„λ‚˜λΌκ²¨μšΈμ΄μ•ΌκΈ°λ‹˜μ˜ λΈ”λ‘œκ·Έ: AOP - Aspect
πŸ‘¨πŸ»β€πŸ’» μƒˆλ‘œλΉ„λ‹˜μ˜ λΈ”λ‘œκ·Έ: μŠ€ν”„λ§ AOP κ°œλ…
πŸ‘¨πŸ»β€πŸ’» "IT is True"λ‹˜μ˜ λΈ”λ‘œκ·Έ: μŠ€ν”„λ§ AOP μš©μ–΄ 정리

profile
πŸ‘ΎISTP의 개발자 λ„μ „κΈ°πŸ§
post-custom-banner

0개의 λŒ“κΈ€