最近学习了javassist的使用方法。
javassist是一个字节码类库,可以用他来动态生成类,动态修改类等等。
下面是如果用javassist来动态创建一个类的demol
我们需要创建的目标类,如下:
- public class JavassistClass{
- private String name="default";
- public JavassistClass(){
- name="me";
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public void execute(){
- System.out.println(name);
- System.out.println("execute ok");
- }
- }
如下为用javassist来创建类的代码:
- import java.lang.reflect.Method;
- import java.lang.reflect.Modifier;
-
- import javassist.ClassPool;
- import javassist.CtClass;
- import javassist.CtConstructor;
- import javassist.CtField;
- import javassist.CtField.Initializer;
- import javassist.CtMethod;
- import javassist.CtNewMethod;
-
- public class JavassistLearn{
-
-
- public static void main(String[] args) throws Exception{
- ClassPool cp=ClassPool.getDefault();
- CtClass ctClass=cp.makeClass("com.slovef.JavassistClass");
-
- StringBuffer body=null;
-
- CtField ctField=new CtField(cp.get("java.lang.String"), "name", ctClass);
- ctField.setModifiers(Modifier.PRIVATE);
-
- ctClass.addMethod(CtNewMethod.setter("setName", ctField));
- ctClass.addMethod(CtNewMethod.getter("getName", ctField));
- ctClass.addField(ctField, Initializer.constant("default"));
-
-
- CtConstructor ctConstructor=new CtConstructor(new CtClass[]{}, ctClass);
- body=new StringBuffer();
- body.append("{\n name=\"me\";\n}");
- ctConstructor.setBody(body.toString());
- ctClass.addConstructor(ctConstructor);
-
-
- CtMethod ctMethod=new CtMethod(CtClass.voidType,"execute",new CtClass[]{},ctClass);
- ctMethod.setModifiers(Modifier.PUBLIC);
- body=new StringBuffer();
- body.append("{\n System.out.println(name);");
- body.append("\n System.out.println(\"execute ok\");");
- body.append("\n return ;");
- body.append("\n}");
- ctMethod.setBody(body.toString());
- ctClass.addMethod(ctMethod);
- Class<?> c=ctClass.toClass();
- Object o=c.newInstance();
- Method method=o.getClass().getMethod("execute", new Class[]{});
-
- method.invoke(o, new Object[]{});
- }
-
- }
javassist还有一个比较常见的用途是AOP,比如对一些类统一加权限过滤,加日志监控等等。
下面示例如何使用javassist来进行AOP拦截处理
我们对上面例子的JavassistClass类的getName()方法进行拦截前置处理
- package com.taobao.relationrecommend.web.util;
-
- import java.lang.reflect.Method;
-
- import javassist.util.proxy.MethodFilter;
- import javassist.util.proxy.MethodHandler;
- import javassist.util.proxy.ProxyFactory;
-
- public class JavassistLearn{
-
-
- public static void main(String[] args) throws Exception{
- ProxyFactory factory=new ProxyFactory();
-
- factory.setSuperclass(JavassistClass.class);
-
- factory.setFilter(new MethodFilter() {
- @Override
- public boolean isHandled(Method m) {
- if(m.getName().equals("getName")){
- return true;
- }
- return false;
- }
- });
-
- factory.setHandler(new MethodHandler() {
- @Override
- public Object invoke(Object self, Method thisMethod, Method proceed,
- Object[] args) throws Throwable {
-
-
- JavassistClass o=(JavassistClass) self;
- o.setName("haha");
- return proceed.invoke(self, args);
- }
- });
-
- Class<?> c=factory.createClass();
- JavassistClass object=(JavassistClass) c.newInstance();
- System.out.println(object.getName());
-
- }
-
- }
javassist学习
原文:http://www.cnblogs.com/yangmengdx3/p/4492905.html