Spring์์ AOP๊ฐ ๋์ํ๋ ๋ฐฉ์์ ๋ํด์๋ ์ฌ๋ฌ๋ฒ์ ํฌ์คํ
์ ํตํด์ ์์๋ณด์์ต๋๋ค.
AOP๋ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์ด์ฉํด์ ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์ฃผ์
ํ๊ณ ๋์์ํค๋๋ฐ, ๊ทธ๋ ๋ค๋ฉด Spring์์ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์ด๋ป๊ฒ ๋ง๋๋์ง์ ๋ํด์ ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
ํ๋ก์ ๊ฐ์ฒด๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์๋ Dynamic Proxy์ CGLIB๊ฐ ์์ต๋๋ค.
๋ ๋ฐฉ๋ฒ์ ์ฐจ์ด์ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ๋ง๋๋ ๊ณผ์ ์ ๋ํด์ ์ฝ๋๋ฅผ ์์ฑํ๋ฉฐ ์ฒ์ฒํ ์์๋ณด๊ฒ ์ต๋๋ค.
JDK Dynamic Proxy๋ JDK์์ ์ง์ํ๋ ํ๋ก์ ์์ฑ ๋ฐฉ๋ฒ์
๋๋ค.
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด์ผ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์๋ค๋ ํน์ง์ด ์์ต๋๋ค.
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ์ง ์์ Target์ JDK Dynamic Proxy๋ฅผ ์ด์ฉํ ๋ถ๊ฐ๊ธฐ๋ฅ ์ ์ฉ์ด ๋ถ๊ฐ๋ฅํ๋ค๋ ๋จ์ ์ด ์์ต๋๋ค.
JDK Dynamic Proxy๊ฐ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๋ถ๊ฐ๊ธฐ๋ฅ์ ์ ์ฉํ๋ ๊ณผ์ ์ ์ฝ๋๋ก ์์๋ณด๊ฒ ์ต๋๋ค.
์ถ์๋ฉ์๋ talk๋ฅผ ๊ฐ์ง Person ์ธํฐํ์ด์ค๋ฅผ ์์ฑํด์ฃผ๊ฒ ์ต๋๋ค.
talk ๋ฉ์๋๋ฅผ ๊ตฌํํ PersonImpl ๊ตฌํ์ฒด ํด๋์ค๋ ์์ฑํด์ฃผ์์ต๋๋ค.
Invocation Handler๋ฅผ ๊ตฌํํ PersonTarget ํด๋์ค๋ฅผ ์์ฑํด์ฃผ์์ต๋๋ค.
์ด ์ธ๊ฐ์ง ํด๋์ค๋ฅผ ์ด์ฉํด JDK Dynamic Proxy๋ฅผ ์ ์ฉํด๋ณด๊ฒ ์ต๋๋ค.
JDK Dynamic Proxy๋ฅผ ์ ์ฉํ๊ธฐ ์ํด์๋ Proxy ํด๋์ค๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋๋ฐ, JDK Dynamic Proxy๋ Reflection API๋ฅผ ๋ด๋ถ์ ์ผ๋ก ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
Proxy ํด๋์ค์์ ์๋ก์ด ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋ฉ์๋๋ฅผ ๋ณด๊ฒ ์ต๋๋ค.
ClassLoader์ ๊ตฌํํ ์ธํฐํ์ด์ค์ ํด๋์ค ๋ฐฐ์ด, InvocationHandler๋ฅผ ์ธ์๋ก ๋ฐ๊ณ ์์ต๋๋ค.
์ ๊ฐ ์์ฑํ PersonImpl์ ๋ํ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์ถ๋ค๋ฉด ์๋์ ๊ฐ์ด ์์ฑํ๋ฉด ๋ฉ๋๋ค.
์ด์ ํ๋ก์๋ฅผ ์ด์ฉํ์ง ์์ ์์ํ PersonImpl ๊ฐ์ฒด์ ํ๋ก์๋ฅผ ์ด์ฉํด ๋ง๋ proxyPerson ๊ฐ์ฒด๋ฅผ ์ด์ฉํด talk ๋ฉ์๋๋ฅผ ํธ์ถํด ๋ณด๊ฒ ์ต๋๋ค.
ํ๋ก์๋ฅผ ์ ์ฉํ์ง ์์ PersonImpl ์ธ์คํด์ค๋ก talk ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ๋ถ๊ฐ๊ธฐ๋ฅ ์์ด ์ํ๋๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
ํ๋ก์๋ฅผ ์ ์ฉํ proxyPerson ์ธ์คํด์ค๋ก talk ๋ฉ์๋ ํธ์ถ์ ๋ถ๊ฐ๊ธฐ๋ฅ์ด ์ ์ฉ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
ํ๋ก์๊ฐ ์ ์ฉ๋ ๊ฐ์ฒด๋ com.sun.proxy.$Proxy11๋ผ๋ ์ด๋ฆ์ ๊ฐ์ง๊ณ , ํ๋ก์๊ฐ ์ ์ฉ๋์ง ์์ ๊ฐ์ฒด๋ com.adoptpet.server.adopt.exception.PersonImpl ์ผ๋ฐ์ ์ธ ํด๋์ค ์ด๋ฆ์ ๊ฐ์ง๊ณ ์๋ ์ฐจ์ด๋ ํ์ธํ ์ ์์์ต๋๋ค.
JDK Dynamic Proxy๋ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ์ง ์์ผ๋ฉด ํ๋ก์ ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์ ์๋ค๋ ์ ์ด ๋จ์ ์ ๋๋ค.
์ด ๋ถ๋ถ์ ํ์ธํ๊ธฐ ์ํด์ ์ฝ๋๋ฅผ ์๋์ ๊ฐ์ด ๋ฐ๊ฟ๋ณด๊ฒ ์ต๋๋ค.
์ธํฐํ์ด์ค๊ฐ ์๋ PersonImpl ํด๋์ค์ ์ ๋ณด๋ฅผ ๋๊ฒจ์ฃผ๋๋ก ํ๊ฒ ์ต๋๋ค.
์์ธ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
JDK Dynamic Proxy๋ ์ด ์ ๋๋ก ์ ๋ฆฌํ ์ ์๊ฒ ์ต๋๋ค!
CGLIB๋ ํด๋์ค์ ๋ฐ์ดํธ์ฝ๋๋ฅผ ์กฐ์ํ์ฌ Proxy ๊ฐ์ฒด๋ฅผ ์์ฑํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์
๋๋ค.
CGLIB ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํ๋ฉด ์ธํฐํ์ด์ค๊ฐ ์๋ Target์ ๋ํด์๋ Proxy ์์ฑ์ด ๊ฐ๋ฅํฉ๋๋ค.
"rabbit eats carrot" ์ด๋ผ๋ ๊ฐ๋จํ ๋ฌธ์ฅ์ ์ถ๋ ฅํ๋ eat ๋ฉ์๋๋ฅผ ๊ฐ์ง Rabbit ํด๋์ค๋ฅผ ์์ฑํ์ต๋๋ค.
์ด ํด๋์ค์ CGLIB๋ฅผ ์ด์ฉํ์ฌ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ณ ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์ฃผ์
ํด๋ณด๊ฒ ์ต๋๋ค.
CGLIB๋ฅผ ์ฌ์ฉํ ๋๋ InvocationHandler๋ฅผ ํ์ฉํ ํ๋ก์ ๊ฐ์ฒด ์์ฑ์ด ๊ฐ๋ฅํฉ๋๋ค.
์ด ๋ฐฉ์์ผ๋ก ๋จผ์ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์ฃผ์
ํ๋ ์ฝ๋๋ฅผ ์์ฑํด๋ณด๊ฒ ์ต๋๋ค.
Dynamic Proxy๋ฅผ ์ฌ์ฉํ ๋์ ๋น์ทํ์ง๋ง, InvocationHandler์ ํจํค์ง๊ฐ CGLIB ํจํค์ง ์์ ์๋ ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ ์ ์ด ๋ค๋ฆ
๋๋ค.
CGLIB๋ ๋ฐ์ดํธ ์ฝ๋ ์กฐ์๋ฐฉ์์ ์ฌ์ฉํ์ฌ JDK Dynamic Proxy์ ๋นํด ์ฝ 3๋ฐฐ์ ๋ ์ฑ๋ฅ์ด ์ฐ์ํ์ง๋ง, InvocationHandler๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ Reflection API๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๊ทธ ์ด์ ์ ๋๋ฆด ์ ์์ต๋๋ค.
๋ฐ์ดํธ ์ฝ๋ ์กฐ์๋ฐฉ์์ ์ด์ฉํ๋ ํ๋ก์ ๊ฐ์ฒด ์์ฑ ๋ฐฉ์์ ํ์ฉํ๊ธฐ ์ํด์๋ MethodInterceptor๋ฅผ ๊ตฌํํ๋ ๋ฐฉ์์ ์ทจํด์ผ ํ๋๋ฐ ์ด ๋ถ๋ถ์ ์ ์ ํ์ ๋ค๋ค๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
ํ
์คํธ ์ฝ๋๋ฅผ ์์ฑํ์ฌ ์์๋๋ก ์ฝ๋๊ฐ ๋์ํ๋์ง ํ์ธํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
์ด ํ
์คํธ ์ฝ๋๋ฅผ ์คํํด๋ณด๊ฒ ์ต๋๋ค.
๋ถ๊ฐ๊ธฐ๋ฅ์ด ์ ๋์ํ๊ณ ์๊ณ , ์ฌ์ฉํ๊ณ ์๋ Rabbit ์ธ์คํด์ค๋ ํ๋ก์ ๊ฐ์ฒด๊ฐ ๋ง๋ค๋ ๊ฒ๊น์ง ํ์ธ์ด ๋์์ต๋๋ค.
์ด์ MethodInterceptor๋ฅผ ํ์ฉํ ๋ฐฉ๋ฒ์ ์ฌ์ฉํด๋ณด๊ฒ ์ต๋๋ค.
MethodInterceptor ๊ตฌํํ ํด๋์ค๋ฅผ ์์ฑํด์ฃผ๊ณ , ์๊น์ ๊ฐ์ด ํ
์คํธ ์ฝ๋๋ฅผ ์์ฑํ๊ฒ ์ต๋๋ค.
ํ
์คํธ ์ฝ๋๋ฅผ ์คํํด๋ณด๊ฒ ์ต๋๋ค.
InvocationHandler๋ฅผ ์ฌ์ฉํ ๋์ ๋ฌ๋ผ์ง์ ์ setCallback ๋ฉ์๋์ ์ธ์๋ก MethodInterceptor๋ฅผ ๊ตฌํํ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ๋ฃ์ด์ค๋ค๋ ์ ์ ๋๋ค.
์ฝ๋๊ฐ ์ ์์ ์ผ๋ก ๋์ํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
JDK Dynamic Proxy๋ ๊ตฌํํ ์ธํฐํ์ด์ค๊ฐ ์์๋ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์์์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด CGLIB ๋ฐฉ์์์๋ ์ด๋ค ์กฐ๊ฑด์ด ๋ง์กฑ๋์ด์ผ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์์๊น์?
CGLIB ๋ฐฉ์์์๋ Target์ ์์๋ฐ์ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์, ํด๋์ค๊ฐ final ์ด๋ผ๋ฉด ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์๊ณ ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์ ์ฉํ ๋ฉ์๋๊ฐ final ์ด๋ผ๋ฉด ๋ถ๊ฐ ๊ธฐ๋ฅ์ด ์ ์ฉ๋์ง ์์ต๋๋ค.
Rabbit ํด๋์ค๋ฅผ final๋ก ๋ณ๊ฒฝํ๊ณ ํ
์คํธ ์ฝ๋๋ฅผ ์คํํด๋ณด๊ฒ ์ต๋๋ค.
ํด๋์ค๋ฅผ final๋ก ๋ณ๊ฒฝํ ๊ฒฝ์ฐ ์๋ฌ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
Rabbit ํด๋์ค์ eat ๋ฉ์๋๋ฅผ final๋ก ๋ณ๊ฒฝํ๊ณ , run ๋ฉ์๋๋ฅผ ์๋ก ์์ฑํ์ต๋๋ค.
eat์ ํธ์ถํ๋ฉด ๋ถ๊ฐ๊ธฐ๋ฅ์ด ์ ์ฉ๋์ง ์๊ณ , run์ ํธ์ถํ๋ฉด ๋ถ๊ฐ๊ธฐ๋ฅ์ด ์ ์ฉ๋๋์ง ํ
์คํธ ์ฝ๋๋ฅผ ์คํํด๋ณด๊ฒ ์ต๋๋ค.
eat ๋ฉ์๋์ ๋ถ๊ฐ๊ธฐ๋ฅ์ ๋์ํ์ง ์๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
CGLIB๋ฅผ ํ์ฉํ๋ ๋ฐฉ๋ฒ์๋ ์ฌ๋ฌ๊ฐ์ง ๋จ์ ์ด ์กด์ฌํ์ต๋๋ค.
์ด ๋จ์ ๋ค์ ์๋์ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ๋ชจ๋ ํด๊ฒฐ๋์ด ์คํ๋ง์์ ๋ ์ฑ๋ฅ ์ข์ CGLIB๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋์์ต๋๋ค.
์ง๊ธ๊น์ง ์ฝ๋๋ก JDK Dynamic Proxy์ CGLIB ๋ฐฉ์์ ๋น๊ตํด๋ณด์์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด Spring์์๋ ์ด๋ป๊ฒ Proxy๋ฅผ ์ฌ์ฉํ๊ณ ์๋์ง ์ง๊ธ๋ถํฐ ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
์คํ๋ง์์๋ ProxyFactoryBean์ ํ์ฉํ์ฌ ํ๋ก์๋ฅผ ์์ฑํ๋ ๋ฐฉ์์ผ๋ก ํ๋ก์ ๊ฐ์ฒด๋ฅผ ํ์ฉํ AOP๋ฅผ ์ ์ฉํฉ๋๋ค.
๊ตฌํํ ์ธํฐํ์ด์ค๊ฐ ์๋ค๋ฉด JDK Dynamic Proxy๋ฅผ ์ฌ์ฉํ๊ณ , ๊ทธ๋ ์ง ์์๊ฒฝ์ฐ CGLIB๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ์์ผ๋ก ๋์ํด์์ต๋๋ค.
์ธํฐํ์ด์ค ๊ธฐ๋ฐ ํ๋ก์๋ ๋๋๋ก ClassCastException์ ๋ฐ์์ํค๊ธฐ ๋๋ฌธ์, CGLIB๋ฅผ Spring Boot์์ Default๋ก ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
proxy-target-class ์ต์ ์ false๋ก ์ค์ ํ๋ค๋ฉด, JDK Dynamic Proxy๊ฐ ์๋ํ๊ฒ๋ฉ๋๋ค.
AOP๋ฅผ ํ์ฉํ ๋ค์ํ ๊ธฐ๋ฅ์ ๊ฐ๋ฐํ๋ฉด์๋, ์ด๋ป๊ฒ ์ด๋ฐ ๋๋ผ์ด ํธ์์ฑ์ ์ ๊ณตํ ์ ์๋์ง ๋ด๋ถ ๋์์ ๋ํ ์ดํด๋ ํ๋๋ ํ์ง ๋ชปํ์ต๋๋ค.
์ด๋ฒ ํฌ์คํ ์ ๊ณ๊ธฐ๋ก ์์ผ๋ก๋ ๋ด๋ถ ๋์์ ๋ํด ๊ถ๊ธํ ๋ถ๋ถ์ด ์๋ค๋ฉด ์ง์ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์คํํ๋ฉด์ ์ดํดํ๊ณ ๊ผญ ๋ด๋ถ ๋์์ ๋ํด ์ดํดํด์ผ ํ๊ฒ ๋ค๋ ์๊ฐ์ด ๋ค์์ต๋๋ค.
์ค๋๋ ์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!
๊ฐ์ํผํ๊ฐ๋ฐ์๋ ์ค..