๐ก ํ๋ก์(Proxy) ๋?
ํด๋ผ์ด์ธํธ๊ฐ ์ค์ ์ฌ์ฉํ๋ ค๋ ๋์์ธ์ ์์ฒญ์ ๋ฐ์ ์ฒ๋ฆฌํ๋ ์ญํ .
ํ๋ก์์๊ฒ ์์ฒญ์ ๋๊ฒจ๋ฐ์ ์ต์ข ์ฒ๋ฆฌํ๋ ์ค๋ธ์ ํธ๋ ํ๊น(Target).
ํ๊น๊ณผ ํ๋ก์์ธ์ง ํด๋ผ์ด์ธํธ๊ฐ ๊ตฌ๋ณํ ์ ์์ด์ผ ํ๊ธฐ์ ๋์ ๊ฐ์ ์ธํฐํ์ด์ค๋ฅผ ํ์ฅํด์ผ ํจ.
ํ๋ก์๋ ์ฌ์ฉ ๋ชฉ์ ์ ๋ฐ๋ผ 2๊ฐ์ง๋ก ๋๋จ
- ๋ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ ๋ถ์ฌ ⇒ ๋ฐ์ฝ๋ ์ดํฐ ํจํด
- ์ ๊ทผ ์ ์ด ⇒ ํ๋ก์ ํจํด
ํ๋ก์ ํจํด
๊ฐ์ฒด ์์ฑ์ ๋น์ฉ ⇒ ์ต์ํ, ํ์ ์์ ๊น์ง ๋ฏธ๋ฃจ๋๊ฒ ์ข์
- ํ๊น์ ๋ํ ์ ๊ทผ๊ถํ ์ ์ด ๊ฐ๋ฅ
- ์บ์ฑ
ํ๋ก์์ ๋จ์
- ํ๋ก์๊ฐ ๋ฉค๋ฒ๋ณ์๋ก ํ๊น ์ค๋ธ์ ํธ ๊ฐ์ง๊ธฐ์ ํ๊น ์ค๋ธ์ ํธ์ ์ข ์์
- ๋๊ฐ์ ๊ธฐ๋ฅ ์ํํ๋ ํ๋ก์๋ผ๋ ์ฌ๋ฌ ํ๊น์ ์ ์ฉํ๋ ค๋ฉด ํ๊น์ ๊ฐฏ์ ๋งํผ ํ๋ก์ ์์ฑํด์ผ ํ๊ธฐ์ ์ฝ๋ ์ค๋ณต ๋ฐ์
- ํ๋ก์๋ฅผ ์ฌ์ฉํ์ง ์๋ ๋ฉ์๋์๋ ํ๊น์ผ๋ก ์์ํ๋ ๋ฉ์๋ ์์ฑํด์ผ ํจ
⇒ ๋ฆฌํ๋ ์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ํ๋ก์๋ฅผ ๋์ ์ผ๋ก ์์ฑํด์ ํด๊ฒฐํด๋ณด์!
๋ค์ด๋ด๋ฏน ํ๋ก์
์ธํฐํ์ด์ค์ ์ ๋ฌด๋ก ํฌ๊ฒ ๋ถ๋ฅ๋จ
- ์ธํฐํ์ด์ค๊ฐ ์กด์ฌํ๋ ๊ฒฝ์ฐ ⇒ JDK ๋์ ํ๋ก์
- ์ธํฐํ์ด์ค๊ฐ ์๋ ๊ฒฝ์ฐ ⇒ CGLIB
JDK ๋์ ํ๋ก์
๊ตฌํ ํด๋์ค๊ฐ ์๋ ์ธํฐํ์ด์ค๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ก์ ์์ฑ
reflect์ invocationHandler๋ฅผ ๊ตฌํํ๋ฉด ๋ง๋ค ์ ์์
Object proxy = Proxy.newProxyInstance(ClassLoader // ํด๋์ค๋ก๋
, Class<?>[] // ํ๊น์ ์ธํฐํ์ด์ค
, InvocationHandler // ํ๊น์ ์ ๋ณด๊ฐ ํฌํจ๋ Handler
);
Proxy ๊ฐ์ฒด ์์ฑ๋๋ ๊ณผ์
- ProxyFactory๊ฐ ํ๊น์ ์ธํฐํ์ด์ค๋ฅผ ์์ํ Proxy ๊ฐ์ฒด ์์ฑ
- proxy ๊ฐ์ฒด์ invocation Handler๋ฅผ ํฌํจ์์ผ ํ๋์ ๊ฐ์ฒด๋ก ๋ฐํ
public class TestInvocationHandler implements InvocationHandler {
private TargetInterface target; //ํ๊น ์ค๋ธ์ ํธ๋ฅผ ๋ฉค๋ฒ ๋ณ์๋ก ์ ์งํด์ผ ํฉ๋๋ค.
public TestInvocationHandler(TargetInterface target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log.info("ํ๋ก์ ๋ถ๊ฐ๊ธฐ๋ฅ ์์"); //์ฌ๊ธฐ์ ๋ถ๊ฐ๊ธฐ๋ฅ ๋ก์ง์ ์ถ๊ฐ
Object result = method.invoke(target, args); //์ค์ ํ๊น ์ค๋ธ์ ํธ๋ก ์์ฒญ์ ์์ํฉ๋๋ค.
log.info("ํ๋ก์ ๋ถ๊ฐ๊ธฐ๋ฅ ์ข
๋ฃ"); //์ฌ๊ธฐ์ ๋ถ๊ฐ๊ธฐ๋ฅ ๋ก์ง์ ์ถ๊ฐ
return result;
}
}
@Test
void testInvocationHandler(){
TargetInterface target = new TargetImpl();
TestInvocationHandler invocationHandler = new TestInvocationHandler(target);
//ํ๋ก์ ์์ฑ
TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(TargetInterface.class.getClassLoader(), new Class[]{TargetInterface.class}, invocationHandler);
//ํ๋ก์ ์คํ
proxy.run();
log.info("proxy = {}", proxy.getClass());
}
์๋ก์ด ํ๊น์ ๊ธฐ์กด์ ํ๋ก์๋ฅผ ์ ์ฉํ๋ ค๋ฉด ์๋ก์ด ํ๊น์ ์ธํฐํ์ด์ค์ ์ผ์นํ๋ ํ๋ก์ ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ค์ด์ผ ํ๋ ๋ถ๋ถ์ InvocationHandler๋ฅผ ์ฌ์ฉํด ๋์ ์ผ๋ก ์์ฑํด ํด๊ฒฐ
CGLIB
CGLIB์ ๋ฐ์ดํธ ์ฝ๋๋ฅผ ์กฐ์ํ์ฌ ๋์ ์ผ๋ก ํด๋์ค ์์ฑํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MemberService.class); // ํ๊น ํด๋์ค
enhancer.setCallback(MethodInterceptor); // Handler
Object proxy = enhancer.create(); // Proxy ์์ฑ
์ธํฐํ์ด์ค ์์ด concrete ํด๋์ค๋ง ์กด์ฌํด๋ ํ๋ก์ ์์ฑ ๊ฐ๋ฅ
CGLIB์ MethodIntercepter ํตํด ๊ตฌํ๋จ, InvocationHandler์ ๋งค์ฐ ์ ์ฌ
์ฑ๋ฅ์ ์ผ๋ก CGLIB์ด ์ข์
CGLB์ ํ๊น์ ๋ํ ์ ๋ณด๋ฅผ ์ ๊ณต ๋ฐ์ ๋ฐ์ดํธ ์ฝ๋๋ฅผ ์กฐ์ํด์ Proxy๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์ ์ดํ ํธ์ถ์์๋ ์กฐ์๋ ๋ฐ์ดํธ ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉํ์ฌ ์ฑ๋ฅ์ ์ผ๋ก ์ข๋ค.
ํ์ง๋ง ์ด๊ธฐ Spring์์๋ JDK ๋ฐฉ์์ ์ฌ์ฉํ์์
- net.sf.cglib.proxy.Enhancer ์์กด์ฑ ์ถ๊ฐ
- default ์์ฑ์
- ํ๊น์ ์์ฑ์ ๋ ๋ฒ ํธ์ถ
๊ฐ์ ๋ฌธ์ ์ ์ด CGLIB์ ์กด์ฌํ๊ธฐ ๋๋ฌธ์
But, ๋๋ถ๋ถ ๊ฐ์ ๋์ด ํ์ฌ ์คํ๋ง์ ๋ค์ด๋๋ฏน ํ๋ก์๋ CGLIB์ผ๋ก ๊ตฌํ๋จ
์คํ๋ง AOP์ Proxy ๋์
๋ฐํ์ ์๋น(Runtime Weaving)
- Spring AOP๋ ํธ์ถ ์์ ์ IoC ์ปจํ
์ด๋์ ์ํด Proxy Bean์ ์์ฑ
- ์ธํฐํ์ด์ค ์ ๋ฌด์ ๋ฐ๋ผ ๋ฐฉ์ ์ ํ(JDK / CGLIB)
- ๋์ ์ผ๋ก ์์ฑ๋ Proxy Bean์ ํ๊น์ ๋ฉ์๋๊ฐ ํธ์ถ๋๋ ์์ ์ ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ๋ฉ์๋๋ฅผ ํ๋จ ๋ฐ ์ฃผ์
๋ค์ด๋๋ฏน ํ๋ก์์ ๋จ์
- ์ธํฐํ์ด์ค์ ์ ๋ฌด์ ๋ฐ๋ผ JDK ๋์ ํ๋ก์, CGLIB์ผ๋ก ๊ฐ๊ฐ ๊ตฌํํด์ผ ํ์
- ๋ค์ด๋๋ฏน ํ๋ก์๋ฅผ ๊ตฌํํ๋ InvocationHandler์ MethodInterceptor์ ํ๊น ์ค๋ธ์ ํธ๊ฐ ์กด์ฌํด์ผ ํจ
ํ๋ก์ ํฉํ ๋ฆฌ๋?
๋ค์ด๋๋ฏน ํ๋ก์์ ๋จ์ ๋ค์ ํด๊ฒฐํ๊ณ ์ ์์ ์ธํฐํ์ด์ค์ ์ ๋ฌด์ ๋ฐ๋ผ ํ๋ก์๋ฅผ ์์ฑํด์ฃผ๋ ํฉํ ๋ฆฌ
์ฆ, ๊ธฐ์กด ๋ค์ด๋๋ฏน ํ๋ก์์ ํฉํ ๋ฆฌ ํจํด ์ ์ฉ
Advidsor, Advice
๐ก Advisor = Advice + Pointcut
Advice: ํ๊น ์ค๋ธ์ ํธ์ ์ ์ฉํ ๋ถ๊ฐ๊ธฐ๋ฅ์ ๋ด์ ์ค๋ธ์ ํธ
Pointcut: ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์ ์ฉํ ๋์์ธ์ง ํ๋ณํ๋ ํํฐ๋ง ๋ก์ง
ํ๋ก์ ํฉํ ๋ฆฌ์ ๋จ์
- ํ๋ก์๋ฅผ ์ ์ฉํ ์คํ๋ง Bean์ ๊ฐฏ์๋งํผ ํ๋ก์๋ฅผ ์์ฑํด์ Bean์ผ๋ก ๋ฑ๋กํด์ฃผ์ด์ผ ํจ
- ์ปดํฌ๋ํธ ์ค์บ์ผ๋ก ๋ฑ๋ก๋ ์คํ๋ง Bean์๋ ์ ์ฉ ๋ถ๊ฐ๋ฅ
๋น ํ์ฒ๋ฆฌ๊ธฐ(Bean Post Processor)
ํ๋ก์ ํฉํ ๋ฆฌ๊ฐ ๊ฐ์ง๊ณ ์๋ ๋จ์ ์ ํด๊ฒฐํ๊ธฐ ์ํด ๋น์ ๋ฑ๋กํ๊ธฐ ์ ์ ์ํ๋๋๋ก ์กฐ์ํ ์ ์๋ **๋น ํ์ฒ๋ฆฌ๊ธฐ(Bean Post Processor)**๋ฅผ ์ฌ์ฉ
์ฐธ๊ณ
[Spring] ํ๋ก์์ ๋์์ธํจํด (tistory.com)
[Spring] ๋ค์ด๋ด๋ฏน ํ๋ก์(DynamicProxy) (tistory.com)`
'TIL > Spring & Spring Batch' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Spring Batch ์ฑ๋ฅ ์ต์ ํ(1) (0) | 2023.10.28 |
---|---|
[Spring-Batch] ํด๋ผ์ฐ๋ ํ๊ฒฝ์์์ Spring Batch (0) | 2023.10.14 |
๋๊ธ