网站地图 | RSS订阅 老铁博客 - 上海SEO优化|上海网站建设|蜘蛛池出租|站群代搭建
你的位置:首页 » 前端脚本 » 正文

cglib,cglib和jdk动态代理

2020-4-3 14:35:42 | 作者:老铁SEO | 0个评论 | 人浏览

  cglib(CodeGenerationLibrary)是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。


  cglib封装了asm,可以在运行期动态生成新的class。


  cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制。


  原理区别:


  java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。


  1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP


  2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP


  3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换


  如何强制使用CGLIB实现AOP?


  *添加CGLIB库,SPRING_HOME/cglib/*.jar


  *在spring配置文件中加入


  JDK动态代理和CGLIB字节码生成的区别?


  *JDK动态代理只能对实现了接口的类生成代理,而不能针对类


  *CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法


  因为是继承,所以该类或方法最好不要声明成final


  Java动态代理和CGLIB代理在其他方面没什么区别,只有


  在Spring配置文件中配置的区别:


  true


  ***************************************************


  com.gc.impl.TimeBookInterface


  cglib和jdk动态代理


  关于动态代理和静态代理


  当一个对象(客户端)不能或者不想直接引用另一个对象(目标对象),这时可以应用代理模式在这两者之间构建一个桥梁--代理对象。


  按照代理对象的创建时期不同,可以分为两种:


  静态代理:事先写好代理对象类,在程序发布前就已经存在了;


  动态代理:应用程序发布后,通过动态创建代理对象。


  静态代理其实就是一个典型的代理模式实现,在代理类中包装一个被代理对象,然后影响被代理对象的行为,比较简单,代码就不放了。


  其中动态代理又可分为:JDK动态代理和CGLIB代理。


  1.JDK动态代理


  此时代理对象和目标对象实现了相同的接口,目标对象作为代理对象的一个属性,具体接口实现中,可以在调用目标对象相应方法前后加上其他业务处理逻辑。


  代理模式在实际使用时需要指定具体的目标对象,如果为每个类都添加一个代理类的话,会导致类很多,同时如果不知道具体类的话,怎样实现代理模式呢?这就引出动态代理。


  JDK动态代理只能针对实现了接口的类生成代理。


  2.CGLIB代理


  CGLIB(CODEGENERLIZELIBRARY)代理是针对类实现代理,


  主要是对指定的类生成一个子类,覆盖其中的所有方法,所以该类或方法不能声明称final的。


  JDK动态代理和CGLIB代理生成的区别


  JDK动态代理只能对实现了接口的类生成代理,而不能针对类。


  CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法。


  因为是继承,所以该类或方法最好不要声明成final,final可以阻止继承和多态。


  PS:final所修饰的数据具有“终态”的特征,表示“最终的”意思:


  final修饰的类不能被继承。


  final修饰的方法不能被子类重写。


  final修饰的变量(成员变量或局部变量)即成为常量,只能赋值一次。


  final修饰的成员变量必须在声明的同时赋值,如果在声明的时候没有赋值,那么只有一次赋值的机会,而且只能在构造方法中显式赋值,然后才能使用。


  final修饰的局部变量可以只声明不赋值,然后再进行一次性的赋值。


  参考代码


  CGLIB:


  12345678


  publicObjectcreateProxyObject(Objectobj){this.targetObject=obj;Enhancerenhancer=newEnhancer();enhancer.setSuperclass(obj.getClass());enhancer.setCallback(this);ObjectproxyObj=enhancer.create();returnproxyObj;//返回代理对象,返回的对象其实就是一个封装了“实现类”的代理类,是实现类的实例。}


  JDK:


  12345


  publicObjectnewProxy(ObjecttargetObject){//将目标对象传入进行代理this.targetObject=targetObject;


  //注意这个方法的参数,后面是类实现的接口returnProxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),this);//返回代理对象}


  在代码中可以看到,在生成代理类时,传递的是实现类所实现的接口targetObject.getClass().getInterfaces(),所以JDK只能对于接口进行做代理。如果换成类的话,则会抛java.lang.ClassCastException异常。


  在Spring的源码中,可以看到很多生成代理类的代码。


  动态代理的应用


  AOP(Aspect-OrientedProgramming,面向切面编程),AOP包括切面(aspect)、通知(advice)、连接点(joinpoint),实现方式就是通过对目标对象的代理在连接点前后加入通知,完成统一的切面操作。


  实现AOP的技术,主要分为两大类:


  一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;


  二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。


  Spring提供了两种方式来生成代理对象:JDKProxy和Cglib,具体使用哪种方式生成由AopProxyFactory根据AdvisedSupport对象的配置来决定。


  默认的策略是如果目标类是接口,则使用JDK动态代理技术,如果目标对象没有实现接口,则默认会采用CGLIB代理。


  如果目标对象实现了接口,可以强制使用CGLIB实现代理(添加CGLIB库,并在spring配置中加入)。


  cglib动态代理


  1.JDK动态代理


  此时代理对象和目标对象实现了相同的接口,目标对象作为代理对象的一个属性,具体接口实现中,可以在调用目标对象相应方法前后加上其他业务处理逻辑。


  代理模式在实际使用时需要指定具体的目标对象,如果为每个类都添加一个代理类的话,会导致类很多,同时如果不知道具体类的话,怎样实现代理模式呢?这就引出动态代理。


  JDK动态代理只能针对实现了接口的类生成代理。


  2.CGLIB代理


  CGLIB(CODEGENERLIZELIBRARY)代理是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的所有方法,所以该类或方法不能声明称final的。


  如果目标对象没有实现接口,则默认会采用CGLIB代理;


  如果目标对象实现了接口,可以强制使用CGLIB实现代理(添加CGLIB库,并在spring配置中加入)。


  AOP包括切面(aspect)、通知(advice)、连接点(joinpoint),实现方式就是通过对目标对象的代理在连接点前后加入通知,完成统一的切面操作。


  cglib动态代理原理


  1.JDK动态代理


  此时代理对象和目标对象实现了相同的接口,目标对象作为代理对象的一个属性,具体接口实现中,可以在调用目标对象相应方法前后加上其他业务处理逻辑。


  代理模式在实际使用时需要指定具体的目标对象,如果为每个类都添加一个代理类的话,会导致类很多,同时如果不知道具体类的话,怎样实现代理模式呢?这就引出动态代理。


  JDK动态代理只能针对实现了接口的类生成代理。


  2.CGLIB代理


  CGLIB(CODEGENERLIZELIBRARY)代理是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的所有方法,所以该类或方法不能声明称final的。


  如果目标对象没有实现接口,则默认会采用CGLIB代理;


  如果目标对象实现了接口,可以强制使用CGLIB实现代理(添加CGLIB库,并在spring配置中加入)。


  AOP包括切面(aspect)、通知(advice)、连接点(joinpoint),实现方式就是通过对目标对象的代理在连接点前后加入通知,完成统一的切面操作。


  cglib实现原理


  这个当时我自己学习了下,顺便再我的博客里面总结了一下:


  Spring的两种代理JDK和CGLIB的区别浅谈:


  Java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用invokeHandler类来处理;


  而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码的子类来处理。


  1>如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP;


  2>如果目标对象实现了接口,可以强制使用cglib实现AOP;


  3>如果目标对象没有实现了接口,必须采用cglib库,Spring会自动在JDK动态代理和cglib之间转换;

  • 本文来自: 老铁博客,转载请保留出处!欢迎发表您的评论
  • 相关标签:
  • 已有0位网友发表了一针见血的评论,你还等什么?

    必填

    选填

    记住我,下次回复时不用重新输入个人信息

    必填,不填不让过哦,嘻嘻。

    ◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

    相关推荐