CGLib动态代理原理及实现

来源:互联网 发布:最强网络神豪80txt下载 编辑:程序博客网 时间:2024/05/16 03:58

JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑,这种方式实质属于继承,所以不能对final修饰的类进行代理,而子类在拦截方法的时候不会拦截final修饰的方法,因为其无法被覆盖。

使用CGLib动态代理的代码是固定的,但是所需要的jar包有两种模式,一种是单独使用CGLib,需要导入其特有的jar包;一种是与Spring一起来使用,Spring中封装了Cglib的jar包,只需要单独导入CGlib的jar包。

单独使用CGLib的jar包:
这里写图片描述
免费下载地址:http://download.csdn.net/detail/jarremdon/9624537

Spring中导入的jar包:
这里写图片描述

Demo:

//被代理的类package com.zhangyike.cglib;public class Person {    //该方法被final修饰,不能被拦截到,不能被增强    public final void eat() {        System.out.println("我会吃饭!");    }    //该方法可以被拦截到去增强    public void play() {        System.out.println("我会玩儿");    }}//CGLib代理类。package com.zhangyike.cglib;import java.lang.reflect.Method;  //单独使用CGlib导入的jar包import net.sf.cglib.proxy.Enhancer;  import net.sf.cglib.proxy.MethodInterceptor;  import net.sf.cglib.proxy.MethodProxy;  /*与Spring结合导入的jar包,两个执行的结果是一样的import org.springframework.cglib.proxy.Enhancer;import org.springframework.cglib.proxy.MethodInterceptor;import org.springframework.cglib.proxy.MethodProxy;*/public class CGlibProxy implements MethodInterceptor{    //创建代理对象    public Object creatProxy(Object obj){        //创建cglib的核心类        Enhancer enhancer = new Enhancer();        //为其设置父类        enhancer.setSuperclass(obj.getClass());        //设置回调        enhancer.setCallback(this);        //创建代理        return enhancer.create();    }    @Override    public Object intercept(Object proxy, Method method, Object[] args,            MethodProxy methodProxy) throws Throwable {        System.out.println("cglib增强前...");        //执行类未增强前的方法        methodProxy.invokeSuper(proxy, args);        System.out.println("cglib增强后...");        System.out.println();        return null;    }}

执行的结果:
我会吃饭!
cglib增强前…
我会玩儿
cglib增强后…

总结:
CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些。同时,由于CGLib由于是采用动态创建子类的方法,对于final方法,无法进行代理。

0 0
原创粉丝点击