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 {

}

}