[Spring] Spring AOP - Spring์—์„œ๋Š” AOP๋ฅผ ์–ด๋–ป๊ฒŒ ์ด์šฉํ• ๊นŒ?

๋ฐ˜์‘ํ˜•

์•ž์„œ ์šฐ๋ฆฌ๋Š” AOP(Aspect Oriented Programming, ๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ)์— ๋Œ€ํ•œ ๊ธฐ๋ณธ๊ณผ ๊ฐœ๋…์— ๋Œ€ํ•ด ์•Œ์•„๋ดค์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ฝ์–ด๋ณด์ง€ ๋ชปํ–ˆ๋‹ค๋ฉด ์ด ๊ธ€์„ ์ฝ๊ธฐ ์ „ ๋ฐ˜๋“œ์‹œ ์ฝ์–ด๋ณด์‹œ๊ธธ ๊ถŒ์žฅ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

 

2022.05.14 - [Programming/Spring] - [Spring] AOP (Aspect-Oriented Programming) ๊ธฐ๋ณธ๊ณผ ๊ฐœ๋…

 

[Spring] AOP (Aspect-Oriented Programming) ๊ธฐ๋ณธ๊ณผ ๊ฐœ๋…

Spring์—๋Š” AOP(Aspect-Oriented Programming, ๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ)์ด๋ผ๋Š” ํ•ต์‹ฌ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์Œ? OOP(๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ)๋ผ๋Š” ๊ฒƒ์€ ๋“ค์–ด๋ดค๋Š”๋ฐ, AOP๋Š” ๋ฌด์—‡์ผ๊นŒ์š”? AOP vs OOP ? ๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

blog.neonkid.xyz

 

 

 

Spring AOP

์•ž์„œ ๋‹ค๋ฃฌ ์ผ๋ฐ˜์ ์ธ AOP์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Spring AOP ๋˜ํ•œ ํ”„๋ก์‹œ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ Advice๋ฅผ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ผ๋ฐ˜์ ์ธ AOP์™€ ๋‹ฌ๋ฆฌ ProxyFactory๋ฅผ ์ด์šฉํ•ด ํ”„๋ก์‹œ๋กœ ์œ„๋น™ํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , Spring์ด ์ œ๊ณตํ•˜๋Š” ์„ ์–ธ์ ์ธ AOP ๊ตฌ์„ฑ ๋งค์ปค๋‹ˆ์ฆ˜์ธ ProxyFactoryBean ํด๋ž˜์Šค์™€ aop ๋„ค์ž„์ŠคํŽ˜์ด์Šค, @AspectJ ์–ด๋…ธํ…Œ์ด์…˜์™€ ๊ฐ™์€ ์„ ์–ธ์  AOP ๋งค์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•ด ํ”„๋ก์‹œ๋ฅผ ์„ ์–ธ์ ์œผ๋กœ ์ƒ์„ฑํ•˜์—ฌ AOP๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

 

์ข€ ๋” ๊ตฌ์ฒด์ ์œผ๋กœ ํ”„๋ก์‹œ ์ƒ์„ฑ์ด ์–ด๋–ป๊ฒŒ ๋˜๋Š”์ง€ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

Spring์€ ๋Ÿฐํƒ€์ž„ ์‹œ์ ์— ApplicationContext(์Šคํ”„๋ง์—์„œ Bean์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ์ฒด)์˜ Bean์— ์ •์˜๋œ ํฉ์–ด์ง„ ๊ด€์‹ฌ์‚ฌ๋ฅผ ๋ถ„์„ํ•˜๊ณ  ProxyBean์„ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ํ˜ธ์ถœ์ž(Caller)์— Target Bean์„ ์ฃผ์ž…ํ•˜์—ฌ ์ด๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•˜๊ฒŒ ํ•˜๋Š” ๋Œ€์‹  ProxyBean์„ ์ฃผ์ž…ํ•˜์—ฌ ProxyBean์ด ์‹คํ–‰ ์กฐ๊ฑด(์ฆ‰, JoinPoint, PointCut, Advice ๋“ฑ)์„ ๋ถ„์„ํ•˜๊ณ  ์ด์— ๋”ฐ๋ผ ์ ์ ˆํ•œ Advice๋ฅผ ์œ„๋น™ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

๊ทธ๋ ‡๋‹ค๋ฉด Spring AOP๊ฐ€ ์ผ๋ฐ˜์ ์ธ AOP ํ”„๋กœ๊ทธ๋ž˜๋ฐ๋ณด๋‹ค ๋” ๋‹จ์ˆœํ™” ๋˜์—ˆ๋‹ค๊ณ  ํ–ˆ๋Š”๋ฐ, ์–ด๋–ป๊ฒŒ ๋‹จ์ˆœํ™” ๋œ ๊ฒƒ์ผ๊นŒ์š”?

 

 

 

Spring AOP Components

์šฐ๋ฆฌ๋Š” ์ด์ „ ๊ธ€์—์„œ AOP์˜ ๊ฐœ๋…๊ณผ ์šฉ์–ด๋ฅผ ๋‹ค๋ค˜์Šต๋‹ˆ๋‹ค. Spring AOP์—์„œ๋Š” ์ด๋“ค ๊ฐœ๋…์„ ์ข€ ๋” ์‹ฌํ”Œํ•˜๊ฒŒ ๋งŒ๋“ค์—ˆ๋Š”๋ฐ์š”. ๊ฐ ์ข…๋ฅ˜์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

  • Spring JoinPoint

    Spring AOP์˜ JoinPoint๋Š” ์˜ค์ง ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์กฐ์ธํฌ์ธํŠธ๋งŒ์„ ์ œ๊ณตํ•œ๋‹ค. 
    (ํ•˜์ง€๋งŒ ํ•„์š”์— ๋”ฐ๋ผ AspectJ ๊ฐ™์€ ๋‹ค๋ฅธ AOP ๊ตฌํ˜„์ฒด์—์„œ ์ œ๊ณตํ•˜๋Š” ๋‹ค๋ฅธ ์กฐ์ธ ํฌ์ธํŠธ๋„ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅ)

  • Spring Aspect

    Spring AOP์˜ Aspect๋Š” Advisor ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์ด๋‹ค.
    Advisor์˜ ํ•˜์œ„ ์ธํ„ฐํŽ˜์ด์Šค๋กœ PointcutAdvisor์™€ IntroductionAdvisor ๋‘ ๊ฐ€์ง€๊ฐ€ ์กด์žฌํ•œ๋‹ค.

  • Spring Advice

    ํŠน์ • ์กฐ์ธํฌ์ธํŠธ์—์„œ ์‹คํ–‰๋  ์ฝ”๋“œ์ธ Advice๋ฅผ Spring AOP์—์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๊ธฐ๋ณธ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
    (Before, After-Returning, After(finally), Around, Throws, Introduction)

    ์ด ์ค‘์—์„œ๋„ Around๋Š” ์ด์ „ ๊ธ€์—์„œ ๋‹ค๋ค˜๋˜ AOP ์–ผ๋ผ์ด์–ธ์Šค ํ‘œ์ค€์ธ MethodInterceptor๋ฅผ ์ ์šฉํ•˜์˜€๋‹ค.

 

์ด์ „ ๊ธ€๊ณผ ์ฝœ๋ผ๋ณด๋ ˆ์ด์…˜ ์œ ์ง€๋ฅผ ์œ„ํ•ด ์œ„์˜ ์ปดํฌ๋„ŒํŠธ ์ค‘ Spring Advice๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ข€ ๋” Spring AOP์— ๋งž๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

Before ์‹œ์ ์— ์‹คํ–‰ํ•  ์ฝ”๋“œ๋ฅผ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•ด MethodBeforeAdvice ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์˜€๊ณ , After ์‹œ์ ์— ์‹คํ–‰ํ•  ์ฝ”๋“œ๋ฅผ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•ด AfterReturningAdvice๋ฅผ ์“ด ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. MethodInterceptor๋ฅผ ์‚ฌ์šฉํ•ด์„œ๋„ ๊ฐ„๋‹จํžˆ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ๋ณ„๋„์˜ ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•ด ์ •์˜ํ•˜์—ฌ ์„œ๋กœ ๋‹ค๋ฅธ ๊ด€์ ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ์Šต์ž…๋‹ˆ๋‹ค.

 

 

 

ProxyFactory

์ด์ „ ๊ธ€์—์„œ๋„ ์ด๋ฒˆ ๊ธ€์—์„œ๋„ ์šฐ๋ฆฌ๋Š” ProxyFactory๋ฅผ ์ด์šฉํ•˜์—ฌ Advice๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  Target ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋Œ€์ƒ ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค.

 

์ด์ฒ˜๋Ÿผ ProxyFactory ํด๋ž˜์Šค๋Š” Spring AOP์—์„œ ์œ„๋น™๊ณผ ํ”„๋ก์‹œ ์ƒ์„ฑ ๊ณผ์ •์„ ์ œ์–ดํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ด์ „์— ๋‹ค๋ค˜๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ๋‹จ์ผ Target ํด๋ž˜์Šค, ํ•˜๋‚˜์˜ Advice๋ฅผ ์ ์šฉํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ํ•˜๋‚˜์˜ Target ํด๋ž˜์Šค์— ํ•ด๋‹นํ•˜๋Š” ๋ชจ๋“  ๋ฉ”์„œ๋“œ์—๋„ ์ ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๊ทธ ์™ธ์—๋„ ๋™์ผํ•œ ProxyFactory๋ฅผ ์ด์šฉํ•ด ๊ฐ๊ธฐ ๋‹ค๋ฅธ Aspect๋ฅผ ์ ์šฉํ•œ ํ”„๋ก์‹œ๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ๋งŒ๋“ค์–ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ™์€ Target ํด๋ž˜์Šค๋ฅผ ๋„ฃ์—ˆ์ง€๋งŒ removeAdvice ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๊ธฐ์กด์— ์ ์šฉํ•œ SimpleBeforeAdvice๋ฅผ ์ œ๊ฑฐํ•œ ํ›„ SimpleAfterAdvice๋งŒ์„ ๋„ฃ๊ณ , ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์ถœ๋ ฅ์˜ ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

1๋ฒˆ์งธ ์ถœ๋ ฅ์€ ์ˆœ์ˆ˜ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒƒ์ด๊ณ , 2๋ฒˆ์งธ ์ถœ๋ ฅ์€ SimpleBeforeAdvice๋งŒ์„ ์ ์šฉ์‹œ์ผฐ์„ ๋•Œ ํ”„๋ก์‹œ ๊ฐ์ฒด, 3๋ฒˆ์งธ ์ถœ๋ ฅ์€ ๊ธฐ์กด์˜ SimpleBeforeAdvice๋ฅผ ์ œ๊ฑฐํ•˜๊ณ , SimpleAfterAdvice๋งŒ์„ ์ ์šฉ์‹œ์ผฐ์„ ๋•Œ ํ”„๋ก์‹œ ๊ฐ์ฒด์˜ ๋ชจ์Šต์ž…๋‹ˆ๋‹ค.

 

 

 

Spring AOP Proxy

์•ž์„œ Proxy๋Š” Target ํด๋ž˜์Šค๋ฅผ ๊ฐ์‹ธ ์š”์ฒญ์„ ๋Œ€์‹  ๋ฐ›์•„์ฃผ๋Š” Wrapping ํด๋ž˜์Šค๋ผ๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด Proxy๋Š” Weaving์„ ํ†ตํ•ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š”๋ฐ, Spring AOP๋Š” ์ด๋Ÿฌํ•œ ์ƒ์„ฑ ๊ณผ์ •์„ ์•„๋ž˜์˜ ๋‘ ๊ฐ€์ง€๋กœ ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค.

 

  • CGLib Proxy
  • JDK Dynamic Proxy

 

์˜ˆ๋ฅผ ๋“ค๋ฉด OrderService๋ผ๋Š” ์ฃผ๋ฌธ์„ ๊ด€๋ฆฌํ•˜๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ํด๋ž˜์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ํด๋ž˜์Šค์—๋Š” ์ƒˆ๋กœ์šด ์ฃผ๋ฌธ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” save ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋Š”๋ฐ, ์‹ค์ œ๋กœ Spring์ด ์ด ํด๋ž˜์Šค์— ์žˆ๋Š” save ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ OrderService ๊ฐ์ฒด์— ๋ฐ”๋กœ ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ weaving์œผ๋กœ ์ƒ์„ฑ๋œ ํ”„๋ก์‹œ๋ฅผ ํ†ตํ•ด ๊ฐ„์ ‘์ ์œผ๋กœ ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

Spring AOP๋Š” AspectJ์™€ ๋‹ฌ๋ฆฌ Load-Time Weaving์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  Run-Time Weaving ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์•ž์„œ ์„ค๋ช…ํ•œ ๋‘ ๊ฐ€์ง€ ํ”„๋ก์‹œ ์ƒ์„ฑ ๋งค์ปค๋‹ˆ์ฆ˜ ์ค‘ CGLIB Proxy๋Š” Run-Time Weaving์„ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋ก์‹œ์ด๊ณ , Spring AOP๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋ก์‹œ ์ƒ์„ฑ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ CGLIB Proxy๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

JDK Proxy์™€ CGLib Proxy์˜ ๊ฒฐ์ •์ ์ธ ์ฐจ์ด์ ์€ ๋ฐ”๋กœ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ Proxy ๊ฐ์ฒด๋กœ ํ•˜๋ƒ, ํด๋ž˜์Šค๋ฅผ Proxy ๊ฐ์ฒด๋กœ ํ•˜๋ƒ์— ์ฐจ์ด์ธ๋ฐ์š”. ๊ณผ๊ฑฐ์—๋Š” Interface๋กœ ๋จผ์ € ๊ตฌํ˜„ ์ŠคํŽ™์„ ๊ฐ–์ถ˜ ๋‹ค์Œ class๋กœ ๊ตฌํ˜„ํ•˜๋Š” OOP๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด ์ง€๊ธˆ์€ ๋ฐ”๋กœ class๋กœ ์ •์˜ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์€๋ฐ, ์ด์— ๋”ฐ๋ผ์„œ Spring์—์„œ๋„ JDK Proxy๋ฅผ ์‚ฌ์šฉํ• ์ง€ CGLib Proxy๋ฅผ ์‚ฌ์šฉํ• ์ง€๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

 

 

 

CGLib Proxy 

CGLIb๊ฐ€ Proxy๋ฅผ ์ปดํŒŒ์ผ ํƒ€์ž„์ด ์•„๋‹Œ ๋Ÿฐํƒ€์ž„ ์‹œ์ ์— ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ๊นŒ์ง€ ์•Œ์•˜์ง€๋งŒ ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ๊ตฌ๋™๋˜๋Š”์ง€ ์•Œ๋ฉด ๋” ์ข‹๊ฒ ์ฃ ?

 

์ด์ „ ๊ธ€์—์„œ ์šฐ๋ฆฌ๋Š” MethodInterceptor๋ฅผ ํ†ตํ•ด Advice๋ฅผ ๋งŒ๋“ค๊ณ , ProxyFactory๋ฅผ ํ†ตํ•ด ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ–ˆ์—ˆ๋Š”๋ฐ์š”. ์ด ๊ณผ์ •์„ ํ•˜๋‚˜๋กœ ๋ฌถ์€ ๋ชจ๋“ˆ์ด ๋ฐ”๋กœ Enhancer์ž…๋‹ˆ๋‹ค.

 

์ƒˆ๋กœ์šด ํ”„๋ก์‹œ๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค๊ณ  ์žˆ๋Š”๋ฐ์š”. ์ด ๋•Œ ์šฐ๋ฆฌ๊ฐ€ ์ฃผ์–ด์ค€ Target ํด๋ž˜์Šค๋ฅผ superClass๋กœ ์ฃผ๋Š” ๊ฒƒ์„ ๋ณด์•„ ํ•ด๋‹น ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ๋•Œ ์ด๋ฅผ ์ƒ์†ํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

๊ทธ๋ฆฌ๊ณ , ๋งŒ๋“ค์–ด์ง„ ํ”„๋ก์‹œ ๊ฐ์ฒด๋กœ ์š”์ฒญ์ด ๋“ค์–ด์™”์„ ๋•Œ ๊ทธ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„์„œ ๋จผ์ € ์ˆ˜ํ–‰ํ•  ๋กœ์ง์„ ์šฐ๋ฆฌ๊ฐ€ ์ •์˜ํ•œ Advice ๋กœ์ง์œผ๋กœ ๋จผ์ € ๊ฐ„ ํ›„ ์‹ค์ œ ๊ฐ์ฒด์— ์š”์ฒญ์„ ์ „๋‹ฌํ•œ ๋‹ค์Œ, ๋Œ์•„์˜ฌ ๋•Œ๋„ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

๋งˆ์ง€๋ง‰์œผ๋กœ create ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด ๋งŒ๋“ค์–ด์ง„ ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

 

 

create ๋ฉ”์„œ๋“œ๋ฅผ ๋ณด๋ฉด Target ํด๋ž˜์Šค ํƒ€์ž…์„ ์ •์˜ํ•˜๊ณ  ํ•˜์ง€ ์•Š๊ณ ์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์˜ค๋ฒ„๋กœ๋”ฉ ๋œ ๊ฑฐ ์™ธ์—๋Š” ๋ณ„๋‹ค๋ฅธ ๊ฒƒ์ด ์—†์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿฐ ๋‹ค์Œ ์‹ค์ œ ํ”„๋ก์‹œ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ๋ฉ”์„œ๋“œ๋Š” non-static create ๋ฉ”์„œ๋“œ์ด๋ฉฐ ์ด ๋ฉ”์„œ๋“œ๋„ ๋ณด๋ฉด...

 

์ด ๋ฉ”์„œ๋“œ์— 320๋ฒˆ์งธ ์ค„์„ ๋ณด๋ฉด Target ํด๋ž˜์Šค๋“ค์˜ ํƒ€์ž…์„ ๊ฐ€์ ธ์™€ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ, 

 

์‹ค์ œ๋กœ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด classOnly ํ”Œ๋ž˜๊ทธ๊ฐ€ ์ฃผ์–ด์ง„ ๊ฒฝ์šฐ๋Š” ๋‹จ์ˆœํžˆ ํด๋ž˜์Šค ํƒ€์ž„๋งŒ์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ๋Š” Reflection์„ ์ด์šฉํ•ด ํด๋ž˜์Šค๋ฅผ ๋ถ„์„ํ•˜๊ณ  ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

ํด๋ž˜์Šค ์ƒ์„ฑ์ž์— ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’์ด ์žˆ์œผ๋ฉด newInstasnce ๋ฉ”์„œ๋“œ๋ฅผ ๋ถ€๋ฅผ ๋•Œ ํŒŒ๋ผ๋ฏธํ„ฐ ํƒ€์ž…๊ณผ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’์„ ์ฃผ๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋นˆ๊ฐ’๊ณผ ๋นˆ ๋ฐฐ์—ด๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

 

ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ์œ„ ์ฝ”๋“œ์—์„œ create ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ ์ด๋ฏธ argumentType์ด null์ด ๋˜๊ณ  ์žˆ์Œ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

 

๋”ฐ๋ผ์„œ ๋นˆ ์ƒ์„ฑ์ž๋กœ ๋œ (argument๊ฐ€ ๋ชจ๋‘ null์ธ) ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ฒƒ์œผ๋กœ ๋Ÿฐํƒ€์ž„ ์‹œ์ ์— ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

Kotlin์˜ ๊ฒฝ์šฐ ๊ธฐ๋ณธ์ ์œผ๋กœ final ํด๋ž˜์Šค์ด๊ณ , ์‹ฌ์ง€์–ด Java์™€ ๋‹ฌ๋ฆฌ ๋นˆ ์ƒ์„ฑ์ž๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋ฐ, ๊ทธ๋Ÿฌ๋ฉด Kotlin + Spring ์กฐํ•ฉ์€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์ธ๊ฐ€์š”?

 

๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ”ํ‹€๋ฆฐ์˜ plugin์„ ํ†ตํ•ด์„œ ์ปดํŒŒ์ผ ์‹œ์ ์— ๋ชจ๋“  ํด๋ž˜์Šค์— ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋„๋ก ํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋ณธ๋ž˜ Spring์€ Default Constructor(๊ธฐ๋ณธ ์ƒ์„ฑ์ž)๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋ชจ๋“  ๊ฐ์ฒด๋“ค์ด Proxy ๊ฐ์ฒด๋กœ ์ ‘๊ทผํ•˜๋Š”๋ฐ, Spring AOP๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” CGLib Proxy๋Š” ์Šค์Šค๋กœ Default Constructor๋ฅผ ์ƒ์„ฑํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ Spring 4.x ๋ฒ„์ „๋ถ€ํ„ฐ๋Š” Objenesis ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•ด ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ CGLib์—์„œ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค. 

 

 

Objenesis : About

About Objenesis is a small Java library that serves one purpose: To instantiate a new object of a particular class. When would you want this? Java already supports this dynamic instantiation of classes using Class.newInstance(). However, this only works if

objenesis.org

์ด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ์žˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , Spring AOP๊ฐ€ CGLib Proxy๋ฅผ ๊ณ„์† ๊ณ ์ง‘ํ•˜๋Š” ์ด์œ ๋Š” JDK Dynamic Proxy์— ๋น„ํ•ด ์„ฑ๋Šฅ์ด ์ข‹๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. JDK Dynamic Proxy๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ Java Reflection์„ ์ด์šฉํ•˜๋ฉฐ ์ด๋Š” ๊ฝค ๋งŽ์€ ์‹œ๊ฐ„ ๋น„์šฉ์„ ์†Œ๋ชจํ•ฉ๋‹ˆ๋‹ค. 

(๊ทธ๋ฆฌ๊ณ  ํ˜„์žฌ๋Š” CGLib Proxy๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋˜ ๋ฌธ์ œ๋“ค ๋Œ€๋ถ€๋ถ„์„ ๊ฐœ์„  ํ•˜์˜€์Œ)

 

๋งˆ์ง€๋ง‰์œผ๋กœ Kotlin์€ ๊ธฐ๋ณธ์ ์œผ๋กœ final class(์ƒ์†์ด ์•ˆ๋˜๋Š” ํด๋ž˜์Šค)๋กœ ์ฝ”๋“œ๋ฅผ ์ •์˜ํ•˜๋Š”๋ฐ, ์›๋ž˜๋ผ๋ฉด ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ๋งˆ๋‹ค open ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์—ฌ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

ํ•˜์ง€๋งŒ ์ด ๋˜ํ•œ plugin์„ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ, allopen ์ด๋ผ๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํŒŒ์ผ ์‹œ์ ์— ๋ชจ๋“  ํด๋ž˜์Šค๋“ค์„ open class๋กœ ๋ฐ”๊ฟ” ์ปดํŒŒ์ผํ•˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์ž…๋‹ˆ๋‹ค. ์ฐจํ›„ ์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์€ plugin.spring์ด๋ผ๋Š” ๊ฒƒ์— ํก์ˆ˜๋˜๊ณ , ์ฝ”ํ‹€๋ฆฐ + ์Šคํ”„๋ง ์กฐํ•ฉ์„ ์‚ฌ์šฉํ•  ๋•Œ ํ•„์š”ํ•œ ๋ชจ๋“  plugin์œผ๋กœ ๊ด€๋ฆฌ๋˜์–ด ์‚ฌ์šฉํ•ด ์œ„ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

 

 

๋งˆ์น˜๋ฉฐ..

๊ธฐ๋ณธ์ ์œผ๋กœ ํ‘œ์ค€ AOP์™€ Spring AOP์˜ ๋ชจ์Šต์€ ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ‘œ์ค€ AOP ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ—ˆ๋“ค์„ ๋‚ฎ์ถ”๊ณ  ์ตœ๋Œ€ํ•œ ๊ฐ„์†Œํ™”๋œ ๋ชจ์Šต์„ ๋ณด์—ฌ์คฌ์Šต๋‹ˆ๋‹ค.

 

์ด ๊ธ€์„ ํ†ตํ•ด์„œ ์ดˆ๊ธฐ Kotlin์ด ์™œ Spring๊ณผ ์œตํ™”ํ•˜๊ธฐ ์–ด๋ ค์› ๋Š”์ง€๋ฅผ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Spring์€ ์ผ๋ฐ˜ Java์™€ ๋‹ฌ๋ฆฌ ๊ฐ์ฒด ์ ‘๊ทผ ๋ฐฉ๋ฒ•์ด๋‚˜ ์ƒ์„ฑ ๋ฐฉ๋ฒ• ๋“ฑ์ด ๋‹ค๋ฅด๊ณ , ์‹ฌ์ง€์–ด Kotlin์˜ ํด๋ž˜์Šค ๊ตฌํ˜„๊ณผ Java์˜ ํด๋ž˜์Šค ๊ตฌํ˜„ ์—ญ์‹œ ๋‹ฌ๋ž๊ธฐ ๋•Œ๋ฌธ์— ์ดˆ์ฐฝ๊ธฐ ์ฝ”ํ‹€๋ฆฐ ์–ธ์–ด๋กœ Spring์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๊ต‰์žฅํžˆ ์–ด๋ ค์šด ์ผ์ด๋˜ ๊ฒƒ์ด์ฃ .

 

๋‹ค์Œ ๊ธ€์—์„œ๋Š” Spring AOP ์ปดํฌ๋„ŒํŠธ ์ค‘ Spring Advice๋ฅผ ์ข€ ๋” ์ž์„ธํžˆ ๋‹ค๋ค„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 
๋ฐ˜์‘ํ˜•
TAGS.

Tistory Comments