cglib动态代理

来源:互联网 发布:理肤泉b5真假知乎 编辑:程序博客网 时间:2024/05/22 17:29

CGLIB动态代理

      由于jdk中的动态代理通过反射类ProxyInvocationHandler回调接口实现,要求委托类必须实现一个接口,只能对该类接口中定义的方法实现代理,这在实际编程中有一定的局限性。那么我们如何实现类的代理呢?

CGLIB概念

       CGLIB(Code Generation Library)是一个开源项目,是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口,通俗说cglib可以在运行时动态生成字节码。

CGLIB原理

      cglib继承被代理的类,重写方法,织入通知,动态生成字节码并运行,因为是继承,所以final类是没有办法动态代理的。

CGLIB动态代理具体例子

public class DynamicProxy implements MethodInterceptor {15 16     // 被代理对象17     Object targetObject;18 19     //Generate a new class if necessary and uses the specified callbacks (if any) to create a new object instance. 20     //Uses the no-arg constructor of the superclass.21     //动态生成一个新的类,使用父类的无参构造方法创建一个指定了特定回调的代理实例22     public Object getProxyObject(Object object) {23         this.targetObject = object;24         //增强器,动态代码生成器25         Enhancer enhancer=new Enhancer();26         //回调方法27         enhancer.setCallback(this);28         //设置生成类的父类类型29         enhancer.setSuperclass(targetObject.getClass());30         //动态生成字节码并返回代理对象31         return enhancer.create();32     }33 34     // 拦截方法35     public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {36         // 被织入的横切内容,开始时间 before37         long start = System.currentTimeMillis();38         lazy();39 40         // 调用方法41         Object result = methodProxy.invoke(targetObject, args);42 43         // 被织入的横切内容,结束时间44         Long span = System.currentTimeMillis() - start;45         System.out.println("共用时:" + span);46         47         return result;48     }49 50     // 模拟延时51     public void lazy() {52         try {53             int n = (int) new Random().nextInt(500);54             Thread.sleep(n);55         } catch (InterruptedException e) {56             e.printStackTrace();57         }58     }59 60 }
CGLIB动态代理与JDK动态代理区别
1、jdk动态代理生成的代理类和委托类实现了相同的接口;
2、cglib动态代理中生成的字节码更加复杂,生成的代理类是委托类的子类,且不能处理被final关键字修饰的方法;
3、jdk采用反射机制调用委托类的方法,cglib采用类似索引的方式直接调用委托类方法;





原创粉丝点击