JavaAssist를 이용한 Dynamic Proxy 예제
JavaAssist를 이용한 Dynamic Proxy 예제
간단하게.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
public Object CreateMBeanProxy(Object inst, String proxyClassName) throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException, ClassNotFoundException {
try {
ClassPool classPool = ClassPool.getDefault();
CtClass originClass = classPool.get(inst.getClass().getName());
log.debug(inst.getClass().getName());
CtClass proxyInterface = classPool.makeInterface(proxyClassName + "MBean");
CtClass proxyClass = classPool.makeClass(proxyClassName);
/* 인스턴스를 delicate 할 맴버 변수 생성 */
proxyClass.addField(CtField.make("private " + inst.getClass().getName() + " obj;", proxyClass));
/* 인터페이스, 클래스 메소드 복제 시작 */
CtMethod[] originCtClassMethods = originClass.getMethods();
for (CtMethod method : originCtClassMethods) {
/* 기본 메소드 제외 */
if (method.getName().equals("wait") || method.getName().equals("notifyAll") || method.getName().equals("notify") || method.getName().equals("getClass") || method.getName().equals("clone") || method.getName().equals("hashCode")
|| method.getName().equals("finalize") || method.getName().equals("equals")) {
continue;
}
log.debug(method);
/* 인터페이스 생성 */
proxyInterface.addMethod(CtNewMethod.abstractMethod(method.getReturnType(), method.getMethodInfo().getName(), method.getParameterTypes(), method.getExceptionTypes(), proxyInterface));
/* 클래스 메소드 본문 생성 */
String body = "{}";
if (method.getReturnType() == null) {
body = "{ obj." + method.getName() + "($$);}";
} else {
body = "{ return obj." + method.getMethodInfo().getName() + "($$);}";
}
/* 클래스 메소드 생성 */
proxyClass.addMethod(CtNewMethod.make(method.getReturnType(), method.getMethodInfo().getName(), method.getParameterTypes(), method.getExceptionTypes(), body, proxyClass));
}
/* 인터페이스, 클래스 메소드 복제 종료 */
log.debug("public " + proxyClassName + "(" + inst.getClass().getName() + " origin){ this.obj=origin;}");
proxyClass.addMethod(CtMethod.make("public void setOrigin(" + inst.getClass().getName() + " origin){ this.obj=origin;}", proxyClass));
proxyClass.setInterfaces(new CtClass[] { proxyInterface });
Class<?> runtimeProxyClass = proxyClass.toClass(inst.getClass().getClassLoader(), null);
Object proxyInstance = runtimeProxyClass.newInstance();
try {
Method mm = proxyInstance.getClass().getMethod("setOrigin", inst.getClass());
mm.invoke(proxyInstance, inst);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return proxyInstance;
} finally {
}
}