Javassist (二)---------------利用javassist API操作已有类并通过反射调用

已有的一个java bean 类 src下 同一包中

package xidian.lili.test.javassist;

public class Person {
private String name;
private int age;
public Person(){
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}

}

操作

package xidian.lili.test.javassist;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.NotFoundException;
public class Demo02 {
public static void test01() throws NotFoundException, IOException, CannotCompileException{

/**
* 处理类的基本用法
*/

ClassPool pool=ClassPool.getDefault();
//获得已有类
CtClass cc=pool.get("xidian.lili.test.javassist.Person");
//获取字节码
byte[] bytes=cc.toBytecode();
System.out.println(Arrays.toString(bytes));
System.out.println(cc.getName());//xidian.lili.test.javassist.Person
System.out.println(cc.getSimpleName());//Person
System.out.println(cc.getModifiers());//1
System.out.println(cc.getSuperclass());
System.out.println(cc.getPackageName());//xidian.lili.test.javassist
}

public static void test02() throws NotFoundException, CannotCompileException, Exception, IllegalArgumentException, InvocationTargetException {

/**
* 处理方法的基本用法
*/

ClassPool pool=ClassPool.getDefault();
//获得已有类
CtClass cc=pool.get("xidian.lili.test.javassist.Person");
//第一种创建新方法
/*
CtMethod m1=CtMethod.make("int add(int a,int b){System.out.println(a+b);return a+b;}", cc);
*/

//第二种创建新方法 返回值类型 方法名 参数 对象

CtMethod m1=new CtMethod(CtClass.intType,"add",
new CtClass[]{CtClass.intType,CtClass.intType}, cc);
m1.setModifiers(Modifier.PUBLIC);
//[source error] no such field: a找不到参数a  字节码的方式统一读入  不知道哪个是a 需要占位符$1第一个参数 $2第二个参数$0this
//m1.setBody("{System.out.println(a+b);return a+b;}");
m1.setBody("{System.out.println($1+$2);return $1+$2;}");
cc.addMethod(m1);

//通过反射调用新方法

Class c1=cc.toClass();
Person p=(Person) c1.newInstance();
Method m=c1.getDeclaredMethod("add", int.class,int.class);
m.invoke(p, new Object[]{3,4});

}
public static void test03() throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{

/**
  * AOP操作  对已有方法进行修改
  */

ClassPool pool=ClassPool.getDefault();
CtClass cc=pool.get("xidian.lili.test.javassist.Person");
CtMethod m2=cc.getDeclaredMethod("setName");
m2.insertBefore("{System.out.println(\"准备修改名字\");}");
m2.insertAfter("{System.out.println(\"修改名字完成\");}");
//通过反射调用
Class s=cc.toClass();
Object obj=s.newInstance();
Method m=s.getDeclaredMethod("setName",String.class);
m.invoke(obj, "lili");

}
public static void test04() throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {

/**
* 对于属性的操作
* 添加新的属性
* 生成setter getter方法
*/

ClassPool pool=ClassPool.getDefault();
CtClass cc=pool.get("xidian.lili.test.javassist.Person");

//第一种
//CtField f2=CtField.make("private String school;", cc)
//第二种
CtField f1=new CtField(pool.get("java.lang.String"), "school", cc);
f1.setModifiers(Modifier.PRIVATE);
cc.addField(f1);
//生成setter getter方法 可以用生成Method方法来做或者如下
cc.addMethod(CtNewMethod.getter("getSchool", f1));
cc.addMethod(CtNewMethod.setter("setSchool", f1));

//通过反射调用
Class c=cc.toClass();
Object o=c.newInstance();
Method m=c.getDeclaredMethod("setSchool", String.class);
m.invoke(o,"西电");
Field f=c.getDeclaredField("school");

//System.out.print(f.get(o));//错误  属性是私有的  本能调用
f.setAccessible(true);

System.out.print(f.get(o));

}

/**
* 对构造器操作类似于普通方法 

* CtConstructor []cons=cc.getConstructors();
* 对于注解的操作
* Object [] annos=cc.getAnnotations();
* 获取全部注解

*/

public static void main(String[] args) throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException  {
//test01();
//test02();
//test03();
test04();
}
}

猜你喜欢

转载自blog.csdn.net/wangdongli_1993/article/details/80979822