Cglib和jdk动态代理的区别

动态代理解决了方法之间的紧耦合,

IOC解决了类与类之间的紧耦合!

Cglib和jdk动态代理的区别?

1、Jdk动态代理:利用拦截器(必须实现InvocationHandler)加上反射机制生成一个代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理

2、 Cglib动态代理:利用ASM框架,对代理对象类生成的class文件加载进来,通过修改其字节码生成子类来处理

什么时候用cglib什么时候用jdk动态代理?

1、目标对象生成了接口 默认用JDK动态代理

2、如果目标对象使用了接口,可以强制使用cglib

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

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

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

2、Cglib是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,并覆盖其中方法的增强,但是因为采用的是继承,所以该类或方法最好不要生成final,对于final类或方法,是无法继承的

Cglib比JDK快?

1、cglib底层是ASM字节码生成框架,但是字节码技术生成代理类,在JDL1.6之前比使用java反射的效率要高

2、在jdk6之后逐步对JDK动态代理进行了优化,在调用次数比较少时效率高于cglib代理效率

3、只有在大量调用的时候cglib的效率高,但是在1.8的时候JDK的效率已高于cglib

4、Cglib不能对声明final的方法进行代理,因为cglib是动态生成代理对象,final关键字修饰的类不可变只能被引用不能被修改

Spring如何选择是用JDK还是cglib?

1、当bean实现接口时,会用JDK代理模式

2、当bean没有实现接口,用cglib实现

3、可以强制使用cglib(在spring配置中加入<aop:aspectj-autoproxy proxyt-target-class=”true”/>)

一. Cglib原理

动态生成一个要代理的子类,子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截技术拦截所有的父类方法的调用,顺势织入横切逻辑,它比Java反射的jdk动态代理要快

Cglib是一个强大的、高性能的代码生成包,它被广泛应用在许多AOP框架中,为他们提供方法的拦截

最底层的是字节码Bytecode,字节码是java为了保证依次运行,可以跨平台使用的一种虚拟指令格式

在字节码文件之上的是ASM,只是一种直接操作字节码的框架,应用ASM需要对Java字节码、class结构比较熟悉

位于ASM上面的是Cglib,groovy、beanshell,后来那个种并不是Java体系中的内容是脚本语言,他们通过ASM框架生成字节码变相执行Java代码,在JVM中程序执行不一定非要写java代码,只要能生成java字节码,jvm并不关系字节码的来源

位于cglib、groovy、beanshell之上的就是hibernate和spring AOP

最上面的是applications,既具体应用,一般是一个web项目或者本地跑一个程序、

使用cglib代码对类做代理?

使用cglib定义不同的拦截策略?

构造函数不拦截方法

用MethodInterceptor和Enhancer实现一个动态代理

Jdk中的动态代理

JDK中的动态代理是通过反射类Proxy以及InvocationHandler回调接口实现的,但是JDK中所有要进行动态代理的类必须要实现一个接口,也就是说只能对该类所实现接口中定义的方法进行代理,这在实际编程中有一定的局限性,而且使用反射的效率也不高

Cglib实现

使用cglib是实现动态代理,不受代理类必须实现接口的限制,因为cglib底层是用ASM框架,使用字节码技术生成代理类,你使用Java反射的效率要高,cglib不能对声明final的方法进行代理,因为cglib原理是动态生成被代理类的子类

Cglib的第三方库提供的动态代理

/*** 动态代理:*  特点:字节码随用随创建,随用随加载*  作用:不修改源码的基础上对方法增强*  分类:*      基于接口的动态代理*      基于子类的动态代理*  基于子类的动态代理:*      涉及的类:Enhancer*      提供者:第三方cglib库*  如何创建代理对象:*      使用Enhancer类中的create方法*  创建代理对象的要求:*      被代理类不能是最终类*  newProxyInstance方法的参数:在使用代理时需要转换成指定的对象*      ClassLoader:类加载器*          他是用于加载代理对象字节码的。和被代理对象使用相同的类加载器。固定写法*      Callback:用于提供增强的代码*          他是让我们写如何代理。我们一般写一个该接口的实现类,通常情况加都是匿名内部类,但不是必须的。*          此接口的实现类,是谁用谁写。*          我们一般写的都是该接口的子接口实现类,MethodInterceptor*/
com.dynamic.cglib.Producer cglibProducer= (com.dynamic.cglib.Producer) Enhancer.create(com.dynamic.cglib.Producer.class,new MethodInterceptor() {/***  执行被代理对象的任何方法都会经过该方法* @param obj* @param method* @param args*      以上三个参数和基于接口的动态代理中invoke方法的参数是一样的* @param proxy:当前执行方法的代理对象* @return* @throws Throwable*/@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {Object returnValue=null;Float money=(Float)args[0];if("saleProduct".equals(method.getName())){returnValue= method.invoke(producer,money*0.8f);}return returnValue;}}
);
cglibProducer.saleProduct(100.0f);

JDK本身提供的动态代理实现

/*** 动态代理:*  特点:字节码随用随创建,随用随加载*  作用:不修改源码的基础上对方法增强*  分类:*      基于接口的动态代理*      基于子类的动态代理*  基于接口的动态代理:*      涉及的类:proxy*      提供者:Jdk官方*  如何创建代理对象:*      使用Proxy类中的newProxyInstance方法*  创建代理对象的要求:*      被代理类最少实现一个接口,如果没有则不能使用*  newProxyInstance方法的参数:在使用代理时需要转换成指定的对象*      ClassLoader:类加载器*          他是用于加载代理对象字节码的。和被代理对象使用相同的类加载器。固定写法*      Class[]:字节码数组*          它是用于让代理对象和被代理对象有相同方法。固定写法*      InvocationHandler:用于提供增强的代码*          他是让我们写如何代理。我们一般写一个该接口的实现类,通常情况加都是匿名内部类,但不是必须的。*          此接口的实现类,是谁用谁写。*/IProducer proxyProducer=  (IProducer) Proxy.newProxyInstance(producer.getClass().getClassLoader(),producer.getClass().getInterfaces(),new InvocationHandler() {/*** 作用:执行被代理对象的任何接口方法都会经过该方法* @param proxy  代理对象的引用* @param method 当前执行的方法* @param args   当前执行方法所需的参数* @return       和被代理对象有相同返回值* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//                        提供增强的代码
//                        1、获取方法执行的参数Object returnValue=null;Float money=(Float)args[0];if("saleProduct".equals(method.getName())){returnValue= method.invoke(producer,money*0.8f);}return returnValue;}});

JDK和Cglib的区别:

Cglib JDK
是否提供子类代理
是否提供接口代理 是(可强制)
区别 必须依赖于CGLib的类库,但是它需要类来实现任何接口代理的是指定的类生成一个子类,覆盖其中的方法 实现InvocationHandler 使用Proxy.newProxyInstance产生代理对象 被代理的对象必须要实现接口

Cglib和jdk动态代理的区别相关推荐

  1. Cglib和jdk动态代理

    前言:动态代理解决了方法之间的紧耦合,IOC解决了类与类之间的紧耦合. Cglib和jdk动态代理的区别? 1.Jdk动态代理:利用拦截器(必须实现InvocationHandler)加上反射机制生成 ...

  2. 输出cglib以及jdk动态代理产生的class文件

    好奇心重的小伙伴有一种知其然,亦欲知其所以然的特性,我们在spring事务应用中会接触到aop技术,而aop背后隐藏的恰恰是以jdk以及cglib为基础的动态代理技术,博主不才,将自己的学习历程记录于 ...

  3. cglib动态代理和jdk动态代理的区别与应用

    1,引入 如果从一个Controller调用Service的非事务方法a,然后在a里调用事务方法b,b事务生效吗? public void update() {updateActual();int a ...

  4. cglib动态代理和jdk动态代理的区别

    jdk动态代理和cglib动态代理执行时都会生成行的calss文件,jdk生成一个,cglib会生成四个 Jdk动态代理生成一个文件继承proxy类实现代理接口,因为java不能多继承的特性,所以只能 ...

  5. CGLib 和JDK 动态代理对比

    1.JDK 动态代理是实现了被代理对象的接口,CGLib 是继承了被代理对象. 2.JDK 和CGLib 都是在运行期生成字节码,JDK 是直接写Class 字节码,CGLib 使用ASM框架写Cla ...

  6. 面试造火箭系列,栽在了cglib和jdk动态代理

    代理模式 关于代理模式,查阅比较专业的资料是这么定义的:代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 主要解决:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上 ...

  7. cglib和jdk动态代理以及 按指定顺序排列list

    2019独角兽企业重金招聘Python工程师标准>>> package com.proxy.cglib; import java.lang.annotation.Annotation ...

  8. 静态代理,cglib动态代理,jdk动态代理区别以及流程详解

    1.静态代理 静态代理使用的是代理设计模式,不讲高大上的思想,我们直接实战 这是动物接口,其中有一个吃饭方法 这是其中的一只动物,实现了动物接口,覆盖了吃饭方法 现在我们思考,我想要给猫找一个代理,希 ...

  9. Spring系列:代理(jdk动态代理,cglib代理)

    使用代理的目的: 1)为其他对象提供一种代理以控制对这个对象的访问. 2)方便系统的扩展和测试. 举例两个具体情况: (1)如果那个对象是一个是很大的图片,需要花费很长时间才能显示出来,那么当这个图片 ...

最新文章

  1. 简单Android手机APP地图,android最简单手机地图APP(只需5分钟)
  2. 实验八——函数定义及调用总结
  3. “刺激的”2017双11 阿里安全工程师首度揭秘智能风控平台MTEE3
  4. 值此中秋圆月夜 数据天涯共此时
  5. 基于SSM框架的高校实验室管理系统PPT模板
  6. 开课吧:分享一下C语言发展史的点点滴滴
  7. mysql.5.7 linux_mysql 5.7 linux下的安装
  8. Python常用模块实战之ATM和购物车系统再升级
  9. 计算机中ms-dos什么意思,msdos是什么意思
  10. Android修改源码实现root
  11. 周杰伦新专辑预售热点传播分析报告概览
  12. linux下Unison安装
  13. 系统启动故障恢复控制台应用实例
  14. 程序员转行,干什么比较好
  15. 【动态规划】数字三角形c语言
  16. 解决 WKWebView goback执行无效的bug
  17. 轻量级模型设计与部署总结
  18. Android帧率测试
  19. 动作游戏的战斗系统设计
  20. Vue.js 源码分析(五) 基础篇 方法 methods属性详解

热门文章

  1. 如何在 R 中使用 Fisher 的最小显着性差异 (LSD)
  2. 【多目标轨迹预测】Trajectron++:Dynamically-Feasible TrajectoryForecastin With Heterogeneous Data(简化翻译+笔记)
  3. 饮水机自燃引发大火,家中配备火灾报警装置
  4. RJ485接口线序及适用环境
  5. 2021高考查询成绩崩溃,2021高考结束,千万别忘了在这天查成绩
  6. Qt开发总结(20)——Data Visualization
  7. 概率论与数理统计--假设检验
  8. 苏宁从暴跌到涨停 张近东10亿资金对抗做空阴谋
  9. 创建维基WIKI百科和建立百度百科有何不同?
  10. [LinkerScript.18] SECTION命令: Input Section Description : 输入section的基础