javassist生成动态代理有两种方式:
- 方式一:代理工厂方式,与JDk动态代理和CGLIB类似
// 代理工厂方式
public static void testJavassistFactoryProxy() {
// 创建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
// 设置被代理类型
proxyFactory.setSuperclass(User.class);
// 创建代理类的class
Class<ProxyObject> proxyClass = proxyFactory.createClass();
// 创建对象
User userProxy = null;
try {
userProxy= (User)proxyClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if(userProxy != null) {
((ProxyObject)userProxy).setHandler(new MethodHandler() {
// 真实主题
User user = new User();
@Override
public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable {
String beforeStr = "before";
Object str = thisMethod.invoke(user, args);
String afterStr = "after";
return beforeStr + str + afterStr;
}
});
String exeStr = userProxy.exe();
System.out.println(exeStr);
}
}
- 方式二:动态代码
// 动态代码方式
public static void testJavassistDefineClass() throws NotFoundException, CannotCompileException, IllegalAccessException, InstantiationException {
// 创建类池, TRUE表示使用默认路径
ClassPool classPool = new ClassPool();
String className = User.class.getName();
// 创建一个类 UserJavassistProxy
CtClass ctClass = classPool.makeClass(className + "JavassistProxy");
// 添加超类
// 设置 UserJavassistProxy的父类是User
ctClass.setSuperclass(classPool.get(User.class.getName()));
// 添加默认的构造函数
ctClass.addConstructor(CtNewConstructor.defaultConstructor(ctClass));
// 添加属性
ctClass.addField(CtField.make("public " + className
+ " real = new " + className + "()",ctClass));
// 添加方法,里面进行动态代理逻辑
ctClass.addMethod(CtMethod.make("public String exe() {return \"before \" + real.exe() + \" after\";}",ctClass));
Class<User> userProxyClass = ctClass.toClass();
User user = userProxyClass.newInstance();
String exeStr = user.exe();
System.out.println(exeStr);
}
相关类:
package org.crown.lin;
import lombok.Data;
/**
* @author ljq
* @create 2019/10/18 0018
*/
@Data
public class User {
private String name;
private String sex;
private String age;
public String exe() {
return "this is User.exe()";
}
}