在hibernate中采用这种方式实现代理,可以从hibernate中把需要的jar包拿过来:javassist-3.12.0.GA.jar
package com.lzzl.javassistproxy;
public class Demo {
public void forJavassistTest(){
System.out.println("----------执行方法forJavassistTest()-----------");
}
}
package com.lzzl.javassistproxy;
import java.io.FileOutputStream;
import java.io.OutputStream;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.NotFoundException;
//javassist动态代理
public class testjavassist {
public static void main(String[] args) throws Exception{
//这里的实现思路就是在原先生成的class文件中新生成一个方法替代原先的方法,新生成的方法名和原先的方法名一样,在方法体里面调用原先的方法并且实现自己想要添加的逻辑,原先的方法名改掉。
//获取目标类的信息
CtClass ctClass=ClassPool.getDefault().get("com.lzzl.javassistproxy.Demo");
//目标类的方法名
String oldName="forJavassistTest";
//获取目标类的方法实例信息
CtMethod ctMethod=ctClass.getDeclaredMethod(oldName);
String newName=oldName+"$impl";
//将该方法重新命名,并且拷贝到新生成的方法实例中
ctMethod.setName(newName);
//生成新的方法实例
CtMethod newMethod=CtNewMethod.copy(ctMethod,"forJavassistTest",ctClass, null);
//设置新的方法的方法体
StringBuffer sb=new StringBuffer();
sb.append("{System.out.println(\"22222222\");\n")
.append(newName+"($$);\n")
.append("System.out.println(\"11111111111\");\n}");
newMethod.setBody(sb.toString());
//增加新方法
ctClass.addMethod(newMethod);
//类已经更改,注意不能使用A a=new A();,因为在同一个classloader中,不允许装载同一个类两次
Demo a=(Demo)ctClass.toClass().newInstance();
a.forJavassistTest();
//生成字节码文件到指定目录下
byte[] bts = ctClass.toBytecode();
OutputStream out = new FileOutputStream("E:\\work\\myeclipsework\\DynamicProxy\\generateFile\\ProxyDemo.class");
out.write(bts);
out.close();
}
}
输出打印:
22222222
———-执行方法forJavassistTest()———–
11111111111
生成的字节码文件:
package com.lzzl.javassistproxy;
import java.io.PrintStream;
public class Demo
{
public Demo()
{
super();
}
public void forJavassistTest$impl() { System.jdField_out_of_type_JavaIoPrintStream.println("----------执行方法forJavassistTest()-----------"); }
public void forJavassistTest()
{
System.jdField_out_of_type_JavaIoPrintStream.println("22222222");
forJavassistTest$impl();
System.jdField_out_of_type_JavaIoPrintStream.println("11111111111");
}
}