๐ŸŒฑSpring AOP ์ •๋ฆฌํ•˜๊ธฐ

TAEYONG KIMยท2023๋…„ 4์›” 18์ผ
0

AOP(Aspect Oriented Programming)


  • ํ•ต์‹ฌ ๊ด€์‹ฌ ์‚ฌํ•ญ๊ณผ ๊ณตํ†ต(๋ถ€๊ฐ€) ๊ด€์‹ฌ ์‚ฌํ•ญ
    • ์ฃผ๊ฐ€ ๋˜๋Š” ๋กœ์ง์ด ์žˆ๊ณ  ๋ถ€๊ฐ€ ๋˜๋Š” ๋กœ์ง์ด ์žˆ๋Š”๋ฐ ์ด๋ฅผ ํ•ต์‹ฌ๊ณผ ๋ถ€๊ฐ€๋กœ ์˜๋ฏธ๋ฅผ ๋‘˜ ์ˆ˜ ์žˆ๋‹ค. ํ•ต์‹ฌ ๊ด€์‹ฌ ์‚ฌํ•ญ(core concern) ๊ณตํ†ต ๊ด€์‹ฌ ์‚ฌํ•ญ(cross-cutting concern)
    • ๊ธฐ์กด OOP์—์„œ๋Š” ๊ณตํ†ต๊ด€์‹ฌ์‚ฌํ•ญ์„ ์—ฌ๋Ÿฌ ๋ชจ๋“ˆ์—์„œ ์ ์šฉํ•˜๋Š”๋ฐ ์žˆ์–ด ์ค‘๋ณต๋œ ์ฝ”๋“œ๋ฅผ ์–‘์ƒ ํ•˜๋Š” ํ•œ๊ณ„๊ฐ€ ์กด์žฌํ•จ
    • ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด AOP๊ฐ€ ๋“ฑ์žฅ
  • AOP๋Š” application์—์„œ์˜ ๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ ์ฆ‰, ํ•ต์‹ฌ์ ์ธ ๊ธฐ๋Šฅ์—์„œ ๋ถ€๊ฐ€์ ์ธ ๊ธฐ๋Šฅ์„ ๋ถ„๋ฆฌํ•จ
  • ๋ถ„๋ฆฌํ•œ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ Aspect๋ผ๋Š” ๋…ํŠนํ•œ ๋ชจ๋“ˆ ํ˜•ํƒœ๋กœ ๋งŒ๋“ค์–ด์„œ ์„ค๊ณ„ํ•˜๊ณ  ๊ฐœ๋ฐœํ•˜๋Š” ๋ฐฉ๋ฒ•
    Aspect๋„ ๊ฒฐ๊ตญ Class
  • OOP๋ฅผ ์ ์šฉํ•˜์—ฌ๋„ ํ•ต์‹ฌ๊ธฐ๋Šฅ์—์„œ ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ์‰ฝ๊ฒŒ ๋ถ„๋ฆฌ๋œ ๋ชจ๋“ˆ๋กœ ์ž‘์„ฑํ•˜๊ธฐ ์–ด๋ ค์šด ๋ฌธ์ œ์ ์„ AOP๊ฐ€ ํ•ด๊ฒฐ
  • AOP๋Š” ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ Aspect๋กœ ์ •์˜ํ•˜์—ฌ, ํ•ต์‹ฌ๊ธฐ๋Šฅ์—์„œ ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ๋ถ„๋ฆฌํ•จ์œผ๋กœ์จ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์„ ์„ค๊ณ„ํ•˜๊ณ  ๊ตฌํ˜„ํ•  ๋•Œ ๊ฐ์ฒด์ง€ํ–ฅ์ ์ธ ๊ฐ€์น˜๋ฅผ ์ง€ํ‚ฌ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๊ฐœ๋…

๐ŸŒฑ Spring AOP ์šฉ์–ด

์šฉ์–ด์„ค๋ช…
Targetํ•ต์‹ฌ๊ธฐ๋Šฅ์„ ๋‹ด๊ณ  ์žˆ๋Š” ๋ชจ๋“ˆ๋กœ target์€ ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ๋ถ€์—ฌํ•  ๋Œ€์ƒ์ด ๋จ ์—ฌ๊ธฐ์„œ ๋งํ•˜๋Š” ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ œ์™ธํ•œ ๋ถ€๊ฐ€๋ฅผ ์˜๋ฏธํ•œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
Advice์–ด๋Š ์‹œ์ ์— ์–ด๋–ค ๊ณตํ†ต ๊ด€์‹ฌ ๊ธฐ๋Šฅ์„ ์ ์šฉํ• ์ง€ ์ •์˜ ํ•œ ๊ฒƒ์ด๋‹ค. Target์— ์ œ๊ณตํ•  ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ๋‹ด๊ณ  ์žˆ๋Š” ๋ชจ๋“ˆ
JoinPointAspect๊ฐ€ ์ ์šฉ ๋  ์ˆ˜ ์žˆ๋Š” ์ง€์ (method, field) ์ฆ‰, target ๊ฐ์ฒด๊ฐ€ ๊ตฌํ˜„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ชจ๋“  method๋Š” JoinPoint๊ฐ€ ๋จ ์‹ค์งˆ์ ์œผ๋กœ Spring์—์„œ๋Š” method์—์„œ๋งŒ ์ง€์›์„ ํ•ด์ฃผ๋ฉฐ Spring์—์„œ๋Š” Runtime ์‹œ์ ์—์„œ๋งŒ ์ง€์›์„ ํ•ด์คŒ Pointcut์˜ ํ›„๋ณด๊ตฐ์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
Pointcut๊ณตํ†ต ๊ด€์‹ฌ ์‚ฌํ•ญ์ด ์ ์šฉ๋  JoinPoint์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. Advice๋ฅผ ์ ์šฉํ•  target์˜ method๋ฅผ ์„ ๋ณ„ํ•˜๋Š” ์ •๊ทœ ํ‘œํ˜„์‹์œผ๋กœ์„œ Pointcut ํ‘œํ˜„์‹์€ execution์œผ๋กœ ์‹œ์ž‘ํ•˜๊ณ  method์˜ Signature๋ฅผ ๋น„๊ตํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฃผ๋กœ ์ด์šฉ
Aspect์—ฌ๋Ÿฌ ๊ฐ์ฒด์—์„œ ๊ณตํ†ต์œผ๋กœ ์ ์šฉ๋˜๋Š” ๊ณตํ†ต ๊ด€์‹ฌ ์‚ฌํ•ญ(transaction, logging, securityโ€ฆ.) AOP์˜ ๊ธฐ๋ณธ ๋ชจ๋“ˆ Aspect๋Š” Singleton ํ˜•ํƒœ์˜ ๊ฐ์ฒด๋กœ ์กด์žฌ
AdvisorAdvice + pointcut, Advisor๋Š” Spring AOP์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋Š” ํŠน๋ณ„ํ•œ ์šฉ์–ด
Weaving์–ด๋–ค Advice๋ฅผ ์–ด๋–ค Pointcut์— ์ ์šฉ์‹œํ‚ฌ ๊ฒƒ์ธ์ง€์— ๋Œ€ํ•œ ์„ค์ •, ์ฆ‰ Pointcut์— ์˜ํ•ด์„œ ๊ฒฐ์ •๋œ ํƒ€๊ฒŸ์˜ JoinPoint์— ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ์‚ฝ์ž…ํ•˜๋Š” ๊ณผ์ •์„ ๋œปํ•จ AOP์˜ ํ•ต์‹ฌ๊ธฐ๋Šฅ์˜ ์ฝ”๋“œ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์œผ๋ฉด์„œ ํ•„์š”ํ•œ ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ํ•ต์‹ฌ์ ์ธ ์ฒ˜๋ฆฌ ๊ณผ์ •

๐ŸŒฑ Spring์€ ํ”„๋ก์‹œ(Proxy) ๊ธฐ๋ฐ˜ AOP์ง€์›

ํ”„๋ก์‹œ๋ผ๋Š” ๊ฐœ๋…์„ ๋ญ๋ผ๊ณ  ์ดํ•ดํ•˜๋ฉด ์ข‹์„๊นŒ?

Spring์€ Target ๊ฐ์ฒด์— ๋Œ€ํ•œ Proxy๋ฅผ ๋งŒ๋“ค์–ด ์ œ๊ณตํ•˜๋Š”๋ฐ Target์„ ๊ฐ์‹ธ๋Š” Proxy๋Š” ์‹คํ–‰์‹œ๊ฐ„ ์ฆ‰ Runtime์— ์ƒ์„ฑ๋œ๋‹ค. Proxy๋Š” Advice๋ฅผ Target ๊ฐ์ฒด์— ์ ์šฉํ•˜๋ฉด์„œ ์ƒ์„ฑ๋˜๋Š” ๊ฐ์ฒด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค. Advice? ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ๋‹ด๊ณ  ์žˆ๋Š” ๋ชจ๋“ˆ

ํ”„๋ก์‹œ๋Š” ํƒ€๊ฒŸ์„ ๊ฐ์‹ธ์„œ ํƒ€๊ฒŸ์˜ ์š”์ฒญ์„ ๋Œ€์‹  ๋ฐ›์•„์ฃผ๋Š” Wrapping Object, Client์—์„œ Target์„ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋ฉด ํƒ€๊ฒŸ์ด ์•„๋‹Œ ํƒ€๊ฒŸ์ด ๊ฐ์‹ธ๊ณ  ์žˆ๋Š” Proxy๊ฐ€ ํ˜ธ์ถœ๋จ ์ด ๋•Œ ํ”„๋ก์‹œ๋Š” ํƒ€๊ฒŸ ๋ฉ”์†Œ๋“œ ์‹คํ–‰ ์ „ํ›„๋กœ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ์‹คํ–‰ํ•˜๋„๋ก ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. ํ”„๋ก์‹œ ํŒจํ„ด์€ ํƒ€๊ฒŸ ํ•˜๋‚˜ ํ•˜๋‚˜๋งˆ๋‹ค ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ์ •์˜ํ•ด์•ผํ•˜๋ฏ€๋กœ ๋ฒˆ๊ฑฐ๋กญ๊ณ  ์ฝ”๋“œ์˜ ์ค‘๋ณต์ด ์ƒ๊ธด๋‹ค๋Š” ์ ์ด ์žˆ์Œ. ๊ทธ๋ž˜์„œ Spring AOP์—์„œ๋Š” Runtime JDK Dynamic Proxy or CGLIB๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํ”„๋ก์‹œ๋ฅผ ์ƒ์„ฑ.

๐Ÿ“Ž Spring์€ AOP ํ”„๋ก์‹œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ณผ์ •์—์„œ ์ž์ฒด ๊ฒ€์ฆ ๋กœ์ง์„ ํ†ตํ•ด ํƒ€๊ฒŸ์˜ ์ธํ„ฐํŽ˜์ด์Šค ์œ ๋ฌด๋ฅผ ํŒ๋‹จํ•œ๋‹ค. ์ด๋•Œ ํƒ€๊ฒŸ์ด ํ•˜๋‚˜ ์ด์ƒ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋Š” Class๋ผ๋ฉด JDK Dynamic Proxy๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์•„๋‹ˆ๋ฉด CGLIB์˜ ๋ฐฉ์‹์œผ๋กœ AOP ํ”„๋ก์‹œ๋ฅผ ์ƒ์„ฑํ•จ

JDK Dynamic Proxy๋ฅผ ํ†ตํ•œ ์žฅ๋‹จ์ 

  • ์žฅ์ : ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†์Œ
  • ๋‹จ์ : ํ”„๋ก์‹œํ•˜๋ ค๋Š” ํด๋ž˜์Šค๋Š” ๋ฐ˜๋“œ์‹œ ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„์ฒด์—ฌ์•ผ ํ•จ

CGLIB๋ž€?

Code Generator Library์˜ ์•ฝ์ž๋กœ, ํด๋ž˜์Šค์˜ ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋ฅผ ์กฐ์ž‘ํ•˜์—ฌ ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค. CGLIB๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์•„๋‹Œ ํƒ€๊ฒŸ ํด๋ž˜์Šค์— ๋Œ€ํ•ด์„œ๋„ ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ์ค„ ์ˆ˜ ์žˆ๊ณ , ์ด ๊ณผ์ •์—์„œ Enhancer๋ผ๋Š” ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•จ

CGLIB๋Š” ํƒ€๊ฒŸ ํด๋ž˜์Šค์˜ ์ƒ์†์„ ๋ฐ›๊ณ  ํ”„๋ก์‹œ๋ฅผ ์ƒ์„ฑ, ์ด๋•Œ ํƒ€๊ฒŸ ํด๋ž˜์Šค์— ํฌํ•จ๋œ ๋ชจ๋“  ๋ฉ”์†Œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•˜๊ณ , ํƒ€๊ฒŸ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋ฅผ ์กฐ์ž‘ํ•˜์—ฌ ํ”„๋ก์‹œ๋ฅผ ์ƒ์„ฑํ•จ

CGLIB ํ”„๋ก์‹œ๋ฅผ ๊ฐ•์ œ๋กœ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์š”์†Œ์˜ proxy-target-class ์†์„ฑ ๊ฐ’์„ true๋กœ ์„ค์ •

<aop:config proxy-target-class="true"/>

CGLIB์˜ ์žฅ๋‹จ์ 

  • ์žฅ์ : ์ธํ„ฐํŽ˜์ด์Šค ์—†์ด ๋‹จ์ˆœ ํด๋ž˜์Šค๋งŒ์œผ๋กœ๋„ ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•ด ์ค„ ์ˆ˜ ์žˆ์Œ
    ๋ฆฌํ”Œ๋ ‰์…˜์ด ์•„๋‹Œ ๋ฐ”์ดํŠธ ์กฐ์ž‘์„ ์‚ฌ์šฉ, ํƒ€๊ฒŸ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์•Œ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— JDK Dynamic Proxy์— ๋น„ํ•ด ์„ฑ๋Šฅ์ด ์ข‹์Œ
  • ๋‹จ์ : ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•จ. default ์ƒ์„ฑ์ž๊ฐ€ ํ•„์š”, ํƒ€๊ฒŸ์œผ ์ƒ์„ฑ์ž๊ฐ€ ๋‘ ๋ฒˆ ํ˜ธ์ถœ๋จ

References

https://steady-coding.tistory.com/608
https://docs.spring.io/spring-framework/docs/3.0.0.M3/reference/html/ch08s06.html

profile
๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž์˜ ์„ฑ์žฅ๊ธฐ

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