javassist学习

javassist学习

 http://blog.csdn.net/yadandan520_ya/article/details/3956867



最近学习了javassist的使用方法。
javassist是一个字节码类库,可以用他来动态生成类,动态修改类等等。

下面是如果用javassist来动态创建一个类的demol

我们需要创建的目标类,如下:
Java代码  
  1. public class JavassistClass{   
  2.     private String name="default";   
  3.     public JavassistClass(){   
  4.         name="me";   
  5.     }   
  6.         public String getName() {   
  7.         return name;   
  8.     }   
  9.     public void setName(String name) {   
  10.         this.name = name;   
  11.     }   
  12.     public void execute(){   
  13.         System.out.println(name);   
  14.         System.out.println("execute ok");   
  15.     }   
  16. }  
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来创建类的代码:
Java代码  
  1.   
  2. import java.lang.reflect.Method;   
  3. import java.lang.reflect.Modifier;   
  4.   
  5. import javassist.ClassPool;   
  6. import javassist.CtClass;   
  7. import javassist.CtConstructor;   
  8. import javassist.CtField;   
  9. import javassist.CtField.Initializer;   
  10. import javassist.CtMethod;   
  11. import javassist.CtNewMethod;   
  12.   
  13. public class JavassistLearn{   
  14.        
  15.        
  16.     public static void main(String[] args) throws Exception{   
  17.         ClassPool cp=ClassPool.getDefault();   
  18.         CtClass ctClass=cp.makeClass("com.slovef.JavassistClass");   
  19.            
  20.         StringBuffer body=null;   
  21.         //参数  1:属性类型  2:属性名称  3:所属类CtClass   
  22.         CtField ctField=new CtField(cp.get("java.lang.String"), "name", ctClass);   
  23.         ctField.setModifiers(Modifier.PRIVATE);   
  24.         //设置name属性的get set方法   
  25.         ctClass.addMethod(CtNewMethod.setter("setName", ctField));   
  26.         ctClass.addMethod(CtNewMethod.getter("getName", ctField));   
  27.         ctClass.addField(ctField, Initializer.constant("default"));   
  28.            
  29.         //参数  1:参数类型   2:所属类CtClass   
  30.         CtConstructor ctConstructor=new CtConstructor(new CtClass[]{}, ctClass);   
  31.         body=new StringBuffer();   
  32.         body.append("{\n name=\"me\";\n}");   
  33.         ctConstructor.setBody(body.toString());   
  34.         ctClass.addConstructor(ctConstructor);   
  35.            
  36.         //参数:  1:返回类型  2:方法名称  3:传入参数类型  4:所属类CtClass   
  37.         CtMethod ctMethod=new CtMethod(CtClass.voidType,"execute",new CtClass[]{},ctClass);   
  38.         ctMethod.setModifiers(Modifier.PUBLIC);   
  39.         body=new StringBuffer();   
  40.         body.append("{\n System.out.println(name);");   
  41.         body.append("\n System.out.println(\"execute ok\");");   
  42.         body.append("\n return ;");   
  43.         body.append("\n}");   
  44.         ctMethod.setBody(body.toString());   
  45.         ctClass.addMethod(ctMethod);   
  46.         Class<?> c=ctClass.toClass();   
  47.         Object o=c.newInstance();   
  48.         Method method=o.getClass().getMethod("execute"new Class[]{});   
  49.         //调用字节码生成类的execute方法   
  50.         method.invoke(o, new Object[]{});   
  51.     }   
  52.   
  53. }  
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;
		//参数  1:属性类型  2:属性名称  3:所属类CtClass
		CtField ctField=new CtField(cp.get("java.lang.String"), "name", ctClass);
		ctField.setModifiers(Modifier.PRIVATE);
		//设置name属性的get set方法
		ctClass.addMethod(CtNewMethod.setter("setName", ctField));
		ctClass.addMethod(CtNewMethod.getter("getName", ctField));
		ctClass.addField(ctField, Initializer.constant("default"));
		
		//参数  1:参数类型   2:所属类CtClass
		CtConstructor ctConstructor=new CtConstructor(new CtClass[]{}, ctClass);
		body=new StringBuffer();
		body.append("{\n name=\"me\";\n}");
		ctConstructor.setBody(body.toString());
		ctClass.addConstructor(ctConstructor);
		
		//参数:  1:返回类型  2:方法名称  3:传入参数类型  4:所属类CtClass
		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[]{});
		//调用字节码生成类的execute方法
		method.invoke(o, new Object[]{});
	}

}



javassist还有一个比较常见的用途是AOP,比如对一些类统一加权限过滤,加日志监控等等。
下面示例如何使用javassist来进行AOP拦截处理

我们对上面例子的JavassistClass类的getName()方法进行拦截前置处理

Java代码  
  1. package com.taobao.relationrecommend.web.util;   
  2.   
  3. import java.lang.reflect.Method;   
  4.   
  5. import javassist.util.proxy.MethodFilter;   
  6. import javassist.util.proxy.MethodHandler;   
  7. import javassist.util.proxy.ProxyFactory;   
  8.   
  9. public class JavassistLearn{   
  10.        
  11.        
  12.     public static void main(String[] args) throws Exception{   
  13.         ProxyFactory factory=new ProxyFactory();   
  14.         //设置父类,ProxyFactory将会动态生成一个类,继承该父类   
  15.         factory.setSuperclass(JavassistClass.class);   
  16.         //设置过滤器,判断哪些方法调用需要被拦截   
  17.         factory.setFilter(new MethodFilter() {   
  18.             @Override  
  19.             public boolean isHandled(Method m) {   
  20.                 if(m.getName().equals("getName")){   
  21.                     return true;   
  22.                 }   
  23.                 return false;   
  24.             }   
  25.         });   
  26.         //设置拦截处理   
  27.         factory.setHandler(new MethodHandler() {   
  28.             @Override  
  29.             public Object invoke(Object self, Method thisMethod, Method proceed,   
  30.                     Object[] args) throws Throwable {   
  31.                 //拦截后前置处理,改写name属性的内容   
  32.                 //实际情况可根据需求修改   
  33.                 JavassistClass o=(JavassistClass) self;   
  34.                 o.setName("haha");   
  35.                 return proceed.invoke(self, args);   
  36.             }   
  37.         });   
  38.            
  39.         Class<?> c=factory.createClass();   
  40.         JavassistClass object=(JavassistClass) c.newInstance();   
  41.         System.out.println(object.getName());   
  42.            
  43.     }   
  44.   

你可能感兴趣的:(javassist学习)