• javassist学习


    最近学习了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. }  



    如下为用javassist来创建类的代码: 

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




    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.   
      45. }  
  • 相关阅读:
    JQuery源码解读 JQ框架简化( 妙味讲堂
    Mia Fringe官网会员须知
    require.js
    :before与::before的区别
    css----苹果移动端以及小程序滚动模块卡顿的处理
    Vue使用国密SM4加密
    vue + echarts + echarts-gl 实现3D 环状图
    React Hook 初学
    常用阻止默认行为的两种方式
    理解事件触发,事件捕获,事件冒泡
  • 原文地址:https://www.cnblogs.com/yangmengdx3/p/4492905.html
Copyright © 2020-2023  润新知