动态代理:cgib、jdk、java javassist

时间:2022-07-24
本文章向大家介绍动态代理:cgib、jdk、java javassist,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

代理:即为访问对象添加一层控制层,使其间接化,控制层可以为对象访问添加操作属性。

一、cglib:Code Generation library

  • 基于ASM(java字节码操作码)的高性能代码生成包
  • 被许多AOP框架使用
  • 区别于JDK动态代理,cglib不需要实现接口。

实例:

import java.lang.reflect.Method;  
   
 import net.sf.cglib.proxy.Enhancer;  
 import net.sf.cglib.proxy.MethodInterceptor;  
 import net.sf.cglib.proxy.MethodProxy;  
   
   
 public class MyMethodInterceptor implements MethodInterceptor {        
     
 
     public String myFun(String arg){  
         return "hello," + arg ;  
     }  
      
     public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {  
         String methodName = method.getName();  
          
         System. out .println( "[intercept] fun invoked before" );  
         String result = (String)args[0] + "..." ;  
         System. out .println( result );  
         System. out .println( "[intercept] fun invoked after" );  
         return result;       
     }  
      
     public Object createProxy(){  
         Enhancer enhancer = new Enhancer();  
         enhancer.setSuperclass(MyMethodInterceptor. class );  
         enhancer.setCallback( this );  
         return enhancer.create();  
     }  
      
      
     public static void main(String[] args) {  
         MyMethodInterceptor ss = new MyMethodInterceptor();  
         MyMethodInterceptor proxy = (MyMethodInterceptor)ss.createProxy();  

         c1.myFun( "cglib test" );  
          
     }  
   
 } 

通用工具类:

package org.windwant.spring.core.proxy;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * Created by windwant on 2016/6/4.
 */
public class MyCGLIBProxy implements MethodInterceptor {
    private Enhancer enhancer = new Enhancer();
    public Object getProxy(Class clazz){
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("cglib before action");
        Object result = methodProxy.invokeSuper(o, objects);
        System.out.println("cglib after action");
        return result;
    }
}

MyCGLIBProxy p = new MyCGLIBProxy();
Performer pp = (Performer) p.getProxy(XXXX.class);
pp.XXXX();

二、JDK动态代理

package org.windwant.spring.core.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Created by windwant on 2016/6/4.
 */
public class MyJDKProxy implements InvocationHandler{
    private Object targetObject;
    public Object getInstance(Object targetObject){
        this.targetObject = targetObject;
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("proxy: before action");
        Object resutl = method.invoke(targetObject, args);
        System.out.println("proxy: after action");
        return resutl;
    }
}
MyJDKProxy mp = new MyJDKProxy();
XXX ap = (XXX) mp.getInstance(new APerformer());
ap.XX();

三、Java javassist 动态代理

package org.windwant.spring.core.proxy;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;

/**
 * Created by windwant on 2016/9/18.
 */
public class MyJavassistProxy {

    public Object getProxySelf(String clazz, String pClazz, String methodName, String methodBefore, String methodAfter){
        ClassPool cp = ClassPool.getDefault();
        CtClass ct;
        try {
            ct = cp.get(clazz);
            if(pClazz != null){
                ct.setSuperclass(cp.get(pClazz));
            }
            ct.writeFile();
            ct.defrost();
            CtMethod m = ct.getDeclaredMethod(methodName);
            if(methodBefore != null) {
                m.insertBefore(methodBefore);
            }
            if(methodAfter != null) {
                m.insertAfter(methodAfter);
            }
            Class c = ct.toClass();
            return c.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
public void testJavassist(){
    String clazz = "org.windwant.spring.core.proxy.Hello";
    String methodBefore = "{ System.out.println("method before...:"); }";
    String methodAfter = "{ System.out.println("method after...:"); }";
    String pClazz = "org.windwant.spring.core.proxy.HelloP";

    Hello hello = (Hello) new MyJavassistProxy().getProxySelf(clazz, null, "say",
                methodBefore, methodAfter);
    hello.say();
}