博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CGLib动态代理原理及实现
阅读量:5248 次
发布时间:2019-06-14

本文共 1551 字,大约阅读时间需要 5 分钟。

JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了。CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。

   简单的实现举例:

这是一个需要被代理的类,也就是父类,通过字节码技术创建这个类的子类,实现动态代理。

 

public class SayHello {   public void say(){    System.out.println("hello everyone");   }  }

该类实现了创建子类的方法与代理的方法。getProxy(SuperClass.class)方法通过入参即父类的字节码,通过扩展父类的class来创建代理对象。intercept()方法拦截所有目标类方法的调用,obj表示目标类的实例,method为目标类方法的反射对象,args为方法的动态入参,proxy为代理类实例。proxy.invokeSuper(obj, args)通过代理类调用父类中的方法。

 

public class CglibProxy implements MethodInterceptor{   private Enhancer enhancer = new Enhancer();   public Object getProxy(Class clazz){    //设置需要创建子类的类    enhancer.setSuperclass(clazz);    enhancer.setCallback(this);    //通过字节码技术动态创建子类实例    return enhancer.create();   }   //实现MethodInterceptor接口方法   public Object intercept(Object obj, Method method, Object[] args,     MethodProxy proxy) throws Throwable {    System.out.println("前置代理");    //通过代理类调用父类中的方法    Object result = proxy.invokeSuper(obj, args);    System.out.println("后置代理");    return result;   }  }

 

具体实现类:

 

public class DoCGLib {   public static void main(String[] args) {    CglibProxy proxy = new CglibProxy();    //通过生成子类的方式创建代理类    SayHello proxyImp = (SayHello)proxy.getProxy(SayHello.class);    proxyImp.say();   }  }

输出结果:

前置代理  hello everyone  后置代理

 

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

原文链接地址:

转载于:https://www.cnblogs.com/aligege/p/8183526.html

你可能感兴趣的文章
linux zip,tar压缩文件夹 忽略 .git 文件夾
查看>>
Docker 尝试安装rabbitmq实践笔记
查看>>
php 图片旋转和png透明
查看>>
Google Projectsheet Planning 插件的WBS
查看>>
centos 中安裝 php-opcache
查看>>
Win10下使用默认的照片查看器
查看>>
Yii2 中使用ts
查看>>
vagrant laravel.log文件不能打开
查看>>
try install gitlab ce at docker ce
查看>>
centos lamp笔记
查看>>
ssl checker
查看>>
Yii2 使用 npm 安装的包
查看>>
laravel 优化小记
查看>>
PHP 添加 跨域头
查看>>
centos httpd 重啓顯示 `httpd: apr_sockaddr_info_get() failed for`
查看>>
yii2 vendor/bower/jquery/dist not exist
查看>>
Anguarjs http 会先发送一次 Options 请求,
查看>>
cordova 插件发布到 npm
查看>>
学习 Apache FileMatchs 规则
查看>>
linux 将子文件夹的文件复制到 当前目录中
查看>>