摘要:值得一提的是由于采用动态创建子类的方式生成代理对象,所以不能对目标类中的方法进行代理。动态代理中生成的代理类是子类,调试的时候可以看到,打开源码可看到实现了和也就实现方法。
前面讲到了动态代理的底层原理,接下来我们来看一下aop的动态代理.
Spring AOP使用了两种代理机制:一种是基于JDK的动态代理,一种是基于CGLib的动态代理.
①JDK动态代理:使用JDK创建代理有一个限制,它只能为接口创建代理实例.这一点可以从Proxy的接口方法
newProxyInstance(ClassLoader loader,Class [] interfaces,InvocarionHandler h)中看的很清楚
第二个入参 interfaces就是需要代理实例实现的接口列表.
②CGLib:采用底层的字节码技术,可以为一个类创建子类,在子类中采用方法拦截的技术拦截所有父类方法的调用
并顺势织入横切逻辑.
③对比:CGLib所创建的动态代理对象的性能比JDK的高大概10倍,但CGLib在创建代理对象的时间比JDK大概多8倍,所以对于singleton的代理对象或者具有实例池的代理,因为无需重复的创建代理对象,所以比较适合CGLib动态代理技术,反之选择JDK代理。值得一提的是由于CGLib采用动态创建子类的方式生成代理对象,所以不能对目标类中final的方法进行代理。
但是这种实现方式存在三个明显需要改进的地方:
a.目标类的所有方法都添加了横切逻辑,而有时,这并不是我们所期望的,我们可能只希望对业务类中的某些特定的方法添加横切逻辑;
b.我们通过硬编码的方式制定了织入横切逻辑的织入点,即在目标业务方法的开始和结束前织入代码;
c.我们手工编写代理实例的创建过程,为不同类创建代理时,需要分别编写相应的创建代码,无法做到通用;
还有一个问题是:spring依赖注入时,什么时候会创建代理类,有时候是cglib有时候是jdkproxy有时候只是普通实例,有兴趣的可以查阅资料,getBean依赖注入过程,可查看IOC源码。
下面我们举个例子看看aop事务注解是怎么实现的。
JDK动态代理:aop中生成的代理类是JdkDynamicAopProxy子类,debug调试的时候可以看到,打开源码可看到实现了AopProxy和invocationHandler也就实现invoke方法。
invoke关键代码:
// Get the interception chain for this method.加载一系列的拦截器 List
TransactionInterceptor是事务拦截器,所有带有@Transactional注解的方法都会经过拦截器invoke方法拦截,点进方法里面可以发现代码如下:
比如回滚方法点进去发现是获取事务管理器然后回滚
最后看下静态代理,JDK动态代理及cglib动态代理的对比
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/73769.html
摘要:紧接着上节,为了解决静态代理的问题,出现了动态代理,假设动态代理是一个代购公司,私有变量为动态生成的具体的真实对象,可代购对应的产品。这个注释是说提供个一个静态方法来创建代理类和代理实例,它也是所有由此方法创建的代理类的父类。 紧接着上节,为了解决静态代理的问题,出现了动态代理, 假设动态代理是一个代购公司,私有变量Object factory为动态生成的具体的真实对象,可代购对应的产...
摘要:对象什么时候被回收答可达性分析,当发现某个类不被引用,类会被回收类的生命周期与动态代理关系动态代理是没有源文件,直接生成字节码的,加载到上面的。 上节讲到动态代理生成的类为$Proxy0,但是在我们项目里面却不存在,实际我们是用了这个实现类调用了方法,想要知道这个问题,首先要理解类的完整生命周期. 类的完整生命周期 showImg(https://segmentfault.com/im...
摘要:,,面向切面编程。,切点,切面匹配连接点的点,一般与切点表达式相关,就是切面如何切点。例子中,注解就是切点表达式,匹配对应的连接点,通知,指在切面的某个特定的连接点上执行的动作。,织入,将作用在的过程。因为源码都是英文写的。 之前《零基础带你看Spring源码——IOC控制反转》详细讲了Spring容器的初始化和加载的原理,后面《你真的完全了解Java动态代理吗?看这篇就够了》介绍了下...
摘要:总结动态代理的相关原理已经讲解完毕,接下来让我们回答以下几个思考题。 【干货点】 此处是【好好面试】系列文的第12篇文章。文章目标主要是通过原理剖析的方式解答Aop动态代理的面试热点问题,通过一步步提出问题和了解原理的方式,我们可以记得更深更牢,进而解决被面试官卡住喉咙的情况。问题如下 SpringBoot默认代理类型是什么 为什么不用静态代理 JDK动态代理原理 CGLIB动态代理...
阅读 2206·2021-09-24 10:31
阅读 3808·2021-09-22 15:16
阅读 3359·2021-09-22 10:02
阅读 984·2021-09-22 10:02
阅读 1782·2021-09-08 09:36
阅读 1955·2019-08-30 14:18
阅读 590·2019-08-30 10:51
阅读 1847·2019-08-29 11:08