Created
May 28, 2016 19:49
-
-
Save wreulicke/74507a4cda6fb0d147e8e2fa458e4d2c to your computer and use it in GitHub Desktop.
とりあえずjavassistのコード置いておく
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.lang.reflect.Field; | |
import java.lang.reflect.Method; | |
import org.junit.Test; | |
import javassist.CannotCompileException; | |
import javassist.ClassPool; | |
import javassist.CtClass; | |
import javassist.CtConstructor; | |
import javassist.CtField; | |
import javassist.CtMethod; | |
import javassist.CtNewConstructor; | |
import javassist.NotFoundException; | |
import javassist.util.proxy.MethodFilter; | |
import javassist.util.proxy.MethodHandler; | |
import javassist.util.proxy.ProxyFactory; | |
import javassist.util.proxy.ProxyObject; | |
public class SecondTest { | |
@Test | |
public void test() throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException { | |
Class<Hoge> type = Hoge.class; | |
ClassPool pool = ClassPool.getDefault(); | |
CtClass orgCls = pool.get(type.getName()); | |
CtClass cls = pool.makeClass(type.getName() + "$$"); | |
cls.setSuperclass(orgCls); | |
for (CtMethod method : orgCls.getDeclaredMethods()) { | |
if (!(method.getName().equals("testMethod"))) | |
continue; | |
CtMethod newMethod = new CtMethod(method.getReturnType(), method.getName(), method.getParameterTypes(), cls); | |
newMethod.setExceptionTypes(method.getExceptionTypes()); | |
newMethod.setBody("{" | |
+ " System.out.println(String.format(\"hoge:%s\",new Object[]{$1}));" | |
+ " return super." + method.getName() + "($$);" + "}"); | |
cls.addMethod(newMethod); | |
} | |
Hoge hoge = (Hoge) pool.toClass(cls).newInstance(); | |
System.out.println(hoge.testMethod("test"));; | |
} | |
@Test | |
public void proxyTest() throws Exception{ | |
Hoge hoge=new Hoge(); | |
Class<Hoge> type = Hoge.class; | |
ClassPool pool = ClassPool.getDefault(); | |
CtClass orgCls = pool.get(type.getName()); | |
CtClass cls = pool.makeClass(type.getName() + "$$a"); | |
cls.setSuperclass(orgCls); | |
CtField field=CtField.make(Hoge.class.getName()+" test;",cls); | |
cls.addField(field); | |
Hoge hoge2=(Hoge)pool.toClass(cls).newInstance(); | |
System.out.println(hoge2.getClass().getDeclaredFields()[0].getName()); | |
} | |
@Test | |
public void invokeHandlingTest()throws Exception{ | |
Hoge hoge=new Hoge(); | |
Class<Hoge> type = Hoge.class; | |
ClassPool pool = ClassPool.getDefault(); | |
CtClass orgCls = pool.get(type.getName()); | |
CtClass cls = pool.makeClass(type.getName() + "$$proxy"); | |
cls.setSuperclass(orgCls); | |
CtMethod m=orgCls.getDeclaredMethod("call"); | |
orgCls.removeMethod(m); | |
m.insertBefore("System.out.println(\"hogehoge\");"); | |
orgCls.addMethod(m); | |
CtField field=CtField.make(Hoge.class.getName()+" test;",cls); | |
cls.addField(field); | |
field=CtField.make("int nest;",cls); | |
cls.addField(field); | |
CtConstructor constructor=CtNewConstructor.make(new CtClass[]{orgCls}, null,"{test=$1;}",cls); | |
cls.addConstructor(constructor); | |
for (CtMethod method : orgCls.getDeclaredMethods()) { | |
CtMethod newMethod = new CtMethod(method.getReturnType(), method.getName(), method.getParameterTypes(), cls); | |
newMethod.setExceptionTypes(method.getExceptionTypes()); | |
newMethod.setBody("{return test." + method.getName() + "($$);" + "}"); | |
newMethod.insertBefore("nest++;"); | |
newMethod.insertBefore("System.out.println(nest+\" invoke start:"+method.getName()+"\");"); | |
newMethod.insertAfter("nest--;"); | |
newMethod.insertAfter("System.out.println(nest+\" invoke end:"+method.getName()+"\");"); | |
cls.addMethod(newMethod); | |
} | |
Hoge hoge2=(Hoge)pool.toClass(cls).getConstructor(Hoge.class).newInstance(hoge);; | |
Field field2=hoge2.getClass().getDeclaredField("test"); | |
System.out.println(hoge2.testMethod("aaa")); | |
hoge2.call(); | |
} | |
@Test | |
public void proxyTest2() throws Exception{ | |
ProxyFactory f = new ProxyFactory(); | |
f.setSuperclass(Hoge.class); | |
f.setFilter(new MethodFilter() { | |
public boolean isHandled(Method m) { | |
return true; | |
} | |
}); | |
Class c = f.createClass(); | |
MethodHandler mi = new MethodHandler() { | |
int nest=0; | |
public Object invoke(Object self, Method m, Method proceed,Object[] args) throws Throwable { | |
System.out.println(++nest+" start:" + m.getName()); | |
Object result= proceed.invoke(self, args); // execute the original method. | |
System.out.println(nest--+" end:" + m.getName()); | |
return result; | |
} | |
}; | |
Hoge foo = (Hoge)c.newInstance(); | |
((ProxyObject)foo).setHandler(mi); | |
foo.testMethod("hoge"); | |
} | |
} | |
class Hoge { | |
public void call(){ | |
System.out.println("call"); | |
} | |
public String testMethod(String hoge) { | |
call(); | |
return "test"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment