Spring AOP 中 JDK 动态代理和 CGLIB 代理的区别是什么?

推荐答案

在 Spring AOP 中,JDK 动态代理和 CGLIB 代理是两种常见的代理方式,它们的区别主要体现在以下几个方面:

  1. 实现方式

    • JDK 动态代理:基于接口实现,要求目标类必须实现至少一个接口。
    • CGLIB 代理:基于继承实现,通过生成目标类的子类来创建代理对象,不要求目标类实现接口。
  2. 性能

    • JDK 动态代理:在代理接口方法时性能较好,但在代理类方法时性能较差。
    • CGLIB 代理:在代理类方法时性能较好,但在生成代理对象时性能较差。
  3. 依赖

    • JDK 动态代理:无需额外依赖,JDK 自带。
    • CGLIB 代理:需要引入 CGLIB 库。
  4. 适用场景

    • JDK 动态代理:适用于代理接口方法。
    • CGLIB 代理:适用于代理类方法,尤其是没有实现接口的类。

本题详细解读

JDK 动态代理

JDK 动态代理是 Java 标准库提供的一种代理机制,它通过 java.lang.reflect.Proxy 类来创建代理对象。JDK 动态代理的核心是 InvocationHandler 接口,开发者需要实现该接口并在 invoke 方法中定义代理逻辑。

优点

  • 无需引入第三方库,JDK 自带。
  • 对于接口方法的代理性能较好。

缺点

  • 只能代理实现了接口的类。
  • 对于类方法的代理性能较差。

示例代码

-- -------------------- ---- -------
------ --------- ----------- -
    ---- -------
-

------ ----- --------------- ---------- ----------- -
    ---------
    ------ ---- ------ -
        ---------------------------
    -
-

------ ----- ---------------- ---------- ----------------- -
    ------- ------ -------

    ------ ----------------------- ------- -
        ----------- - -------
    -

    ---------
    ------ ------ ------------- ------ ------ ------- -------- ----- ------ --------- -
        ---------------------------
        ------ ------ - --------------------- ------
        ---------------------------
        ------ -------
    -

    ------ ------ ---- ------------- ----- -
        ----------- ----------- - ------------- -----------------------
                -----------------------------------
                --- ---------------------------
                --- -------------------- ------------------
        --
        -------------------
    -
-

CGLIB 代理

CGLIB(Code Generation Library)是一个强大的高性能代码生成库,它通过生成目标类的子类来实现代理。CGLIB 代理的核心是 MethodInterceptor 接口,开发者需要实现该接口并在 intercept 方法中定义代理逻辑。

优点

  • 可以代理没有实现接口的类。
  • 对于类方法的代理性能较好。

缺点

  • 需要引入 CGLIB 库。
  • 在生成代理对象时性能较差。

示例代码

-- -------------------- ---- -------
------ ----- ----------- -
    ------ ---- ------ -
        ---------------------------
    -
-

------ ----- ---------------------- ---------- ----------------- -
    ---------
    ------ ------ ---------------- ---- ------ ------- -------- ----- ----------- ------ ------ --------- -
        ---------------------------
        ------ ------ - ---------------------- ------
        ---------------------------
        ------ -------
    -

    ------ ------ ---- ------------- ----- -
        -------- -------- - --- -----------
        ------------------------------------------
        ------------------------ --------------------------
        ----------- ----------- - ------------- ------------------
        -------------------
    -
-

总结

  • JDK 动态代理:适用于代理接口方法,无需额外依赖,但只能代理实现了接口的类。
  • CGLIB 代理:适用于代理类方法,尤其是没有实现接口的类,但需要引入 CGLIB 库。

在实际开发中,Spring AOP 会根据目标类是否实现了接口自动选择使用 JDK 动态代理还是 CGLIB 代理。如果目标类实现了接口,则使用 JDK 动态代理;否则,使用 CGLIB 代理。

纠错
反馈