Skip to content

Instantly share code, notes, and snippets.

@wreulicke
Created May 28, 2016 19:49
Show Gist options
  • Save wreulicke/74507a4cda6fb0d147e8e2fa458e4d2c to your computer and use it in GitHub Desktop.
Save wreulicke/74507a4cda6fb0d147e8e2fa458e4d2c to your computer and use it in GitHub Desktop.
とりあえずjavassistのコード置いておく
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