转载

面试必问系列之CGLIB动态代理

上一篇讲解了 JDK 的动态代理机制 ,JDK 动态代理的缺点:

  • 问题1 :JDK 动态代理是基于接口实现的,如果类不实现接口,怎么去代理这个类呢?
  • 问题2 :JDK 动态代理的目标类的内部调用自己的另一个方法,不会经过代理对象,那如何解决这个问题呢?

那就了解一下 Spring AOP 的另一个代理机制 cglib 动态代理

2. CGLIB 动态代理

  • 实战CGLIB系列文章之开篇:CGLIB简介、原理与应用
  • 实战CGLib系列之proxy篇(一):方法拦截MethodInterceptor
  • 实战CGLib系列之proxy篇(二):回调过滤CallbackFilter
  • 实战CGLib系列之proxy篇(三):延迟加载LazyLoader
  • 实战CGLib系列之proxy篇(四):改进版延迟加载Dispatcher
  • 实战CGLib系列之proxy篇(五):接口生成器InterfaceMaker
  • Spring Aop之Cglib实现原理详解
  • AOP 的利器:ASM 3.0 介绍
  • 学完 Aop,连动态代理的原理都不懂?

内容我抽空整理,上面这些文章有的年头比较久,看一下了解怎么使用就行。我大概总结一下上面的重点:

  • JDK 动态代理生成代理类继承 Proxy 并且实现代理接口,底层原理是通过反射调用父类的方法。

  • CGLIB 动态代理生成代理类的子类,并且实现了 Factory 接口 ,底层是通过 ASM 进行字节码的增强,然后生成一个新的子类。调用方法就直接调用,不需要再通过反射的方式调用。

  • Spring Boot 2.0 开始代理类默认的实现方式是 cglib,如果想使用 JDK 动态代理,可以通过 spring.aop.proxy-target-class=false 来实现。

    面试必问系列之CGLIB动态代理
  • CGLIB 代理的目标类调用自己的另一个方法,也是会经过代理对象的,因为底层不像 JDK 动态代理的反射方式调用,而是通过动态生成子类的全新方式调用。

  • CGLIB 代理的目标类的方法满足下面条件任意一点,就不会被代理:

    • 使用 final 修饰的方法
    • 使用 private 类型的方法
    • 使用包访问权限
  • CGLIB 代理方法,想要对方法的返回值进行特殊处理,可以使用 CallbackFilter。

3. 总结

通过动态代理的方式增强目标方法,也是实现 Spring AOP 的原理。动态代理有两种方式:JDK 动态代理和 CGLIB 动态代理。这两种代理方式的原理我也已经讲过了,希望大家也可以去实践一下,也可以跟踪一下 Spring 的代码看看底层的原理。

最后头脑风暴一下:为什么 Spring Boot 默认使用 CGLIB 动态代理呢?

扫描下方二维码即可关注微信公众号 小李不秃 ,一起高效学习 Java。

面试必问系列之CGLIB动态代理
原文  https://juejin.im/post/5ef1b2666fb9a05899307dc6
正文到此结束
Loading...