闷棍暴打面试官 Spring源码系列 (二) ​为什么老项目总是用 JDK 动态代理方式 ?

Spring 中的动态代理

张大胖初学 Spring 时, 老师告诉他 Spring AOP 是基于动态代理实现的, 然后就不知所云了. 大胖工作后偶然看了篇博文, 迷迷糊糊知道了 CGlib 与 JDK Agent 都被 Spring Aop 用到了, 这两者同为动态代理技术却还是有差异的,
甚至部分差异影响了 Spring 业务项目的代码风格,

Spring AOP 默认为 AOP 代理使用标准的 J2SE动态代理。这允许代理任何接口(或接口集)。

Spring AOP 也可以使用 CGLIB 代理。这是代理类而不是接口所必需的。如果业务对象未实现接口,则默认使用 CGLIB。由于编程接口而不是类是一种很好的做法,因此业务类通常会实现一个或多个业务接口。
在需要建议未在接口上声明的方法的情况下(希望很少见),或者需要将代理对象作为具体类型传递给方法的情况下,可以强制使用 CGLIB。

引用: https://docs.spring.io/spring-framework/docs/2.5.x/reference/aop.html

为什么老项目的 Service 层总是用接口+实现类 ?

相信接触过老项目的人, 一定对Service层 接口 + 实现类的方式比较眼熟. 而新项目则全部为野蛮注入, 这种情况是怎么发生的呢?

要探究这个问题, 就需要查看老版 Spring 的源码, 看看那时候有没有引入 cglib, 引入程度是如何 ?

Spring AOP 使用 JDK 动态代理或 CGLIB 为给定的目标对象创建代理.(如果您有选择,则首选 JDK 动态代理)。
如果要代理的目标对象至少实现了一个接口,则将使用 JDK 动态代理。目标类型实现的所有接口都将被代理。如果目标对象没有实现任何接口,那么将创建一个 CGLIB 代理。
如果您想强制使用 CGLIB 代理(例如,代理为目标对象定义的每个方法,而不仅仅是由其接口实现的方法),您可以这样做。但是,有一些问题需要考虑:
不能建议final方法,因为它们不能被覆盖。

引用自 Spring 2.5 docs: https://docs.spring.io/spring-framework/docs/2.5.x/reference/aop.html

笔者查看了 Spring 2.0, 3.0, 5.0,最终结果就是,spring 2.0 时期就使用 cglib 代理了,
spring项目里 bean,aop 都用了,后续版本将 cglib 以及asm依赖集中放到了 core 模块中,可能是早期受面向接口编程的影响,以及 Apache Dubbo 的影响

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PUgeh6um-1637388468500)(../../../Image/Open/Technology/Advanced/cglib/spring2-cglib.png)]

Cglib 在 Spring 中负责的岗位

放到以后探讨

Cglib 源码探索

放到以后探讨

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值