【2021-07-06】了解代理模式吗?CGLIB 动态代理与 JDK 动态代理有什么区别?

未匹配的标注

请移步至::octocat:每日一题 查看更多的题目 ~

答:

代理模式是指 “为对象提供一种代理以控制对这个对象的访问”。

简单说就是,之前A自己做一件事,在使用代理之后,A不直接去做,而是由A的代理B来去做。

我们来看一下代理模式的类图:

【2021-07-06】了解代理模式吗?CGLIB 动态代理与 JDK 动态代理有什么区别?

代理模式中的角色:

  • Subject
    Subject 为目标对象和代理对象共同的接口
  • RealSubject
    RealSubject 为被代理的角色,定义了代理对象所代表的目标对象
  • Proxy
    Proxy 是代理类,代理对象持有目标对象的引用,从而可以在任何时候操作目标对象

什么情况下我们需要代理模式?

  • 当我们不想直接访问某个对象时
  • 需要对某个类做方法增强时

静态代理与动态代理:

代理模式可以分为静态代理与动态代理

所谓的静态代理指的是,代理类在程序编译期就生成了对应的 class 文件,而动态代理则是在程序运行时,通过 Java 的反射机制动态创建而成。

关于静态代理与动态代理的代码示例可以参考我的仓库:
github.com/jinrunheng/proxy-patter...

静态代理:github.com/jinrunheng/proxy-patter...

JDK 动态代理:github.com/jinrunheng/proxy-patter...

CGLIB 动态代理:github.com/jinrunheng/proxy-patter...

CGLIB 动态代理和 JDK 动态代理二者有什么区别呢?

  1. JDK 动态代理只能对实现了接口的类生成代理,而不能针对没有接口的目标类生成代理。这里面往往面试官会接着问,为什么 JDK 动态代理是基于接口实现的?其原因是:Java 是单继承的,我们生成的动态代理类在内部已经继承了 Proxy 类,就不能再继承其他的类了,所以只能靠实现被代理类的接口这种形式来实现代理。
  2. CGLIB 是针对类实现的代理,主要是对目标类生成一个子类,并覆盖其方法实现字节码增强,但是因为采用的是继承,所以该类或想要实现增强的方法如果声明了 final 关键字则无法成功。
  3. CGLIB 底层采用 ASM 字节码生成框架,使用字节码生成代理类,在 JDK6 之前效率要高于 JDK 动态代理,不过随着 JDK 版本不断升级与改善,目前 JDK 代理的效率得到了大幅度提升,从 JDK8 之后,其效率是要略高于 CGLIB 的
  4. Spring AOP 提供了 JDK 动态代理以及 CGLIB 动态代理的支持,当 Bean 实现了接口时,Spring 会使用 JDK 动态代理,当 Bean 没有实现接口时,Spring 使用的是 CGLIB 的实现

代理模式的应用:

代理模式最经典的应用为 Spring AOP。

在面向对象中一些公共的行为,像日志记录,权限验证等如果都使用面向对象来做,会在每个业务方法中都写上重复的代码,造成代码的冗余。而AOP指的是面向切面编程,定义一个切面,用切面去切入相应的方法,就可以织入相关的逻辑。面向切面编程(AOP)使用的就是代理模式(JDK 动态代理,CGLIB 动态代理)。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~