• SpringBoot/Spring AOP默认动态代理方式


    • Spring 5.x中AOP默认依旧使用JDK动态代理
    • SpringBoot 2.x开始,AOP为了解决使用JDK动态代理可能导致的类型转换异常,而使用CGLIB。
    • 在SpringBoot 2.x中,AOP如果需要替换使用JDK动态代理可以通过配置项spring.aop.proxy-target-class=false来进行修改,proxyTargetClass配置已无效。

    1. springboot 2.x 及以上版本 

            在 SpringBoot 2.x AOP中会默认使用Cglib来实现,但是Spring5中默认还是使用jdk动态代理。Spring AOP 默认使用 JDK 动态代理,如果对象没有实现接口,则使用 CGLIB 代理。当然,也可以强制使用 CGLIB 代理。

    在 SpringBoot 中,通过AopAutoConfiguration来自动装配AOP.

    2. Springboot 1.x

    Springboot 1.x AOP默认还是使用 JDK 动态代理的

     3.SpringBoot 2.x 为何默认使用 Cglib

            因为JDK 动态代理是基于接口的,代理生成的对象只能赋值给接口变量。JDK动态代理使用Proxy.newProxyInstance()创建代理实现类,然而第二个参数就需要接口类型,如果没有接口类型就会报错。

    Proxy.newProxyInstance(iCustomerInstance.getClass().getClassLoader(), iCustomerInstance.getClass().getInterfaces(), this);
    

    而 CGLIB 就不存在这个问题。因为 CGLIB 是通过生成子类来实现的,代理对象无论是赋值给接口还是实现类,这两者都是代理对象的父类。

    所以在2.x版本以上,将 AOP 默认实现改为了 CGLIB代理。

    新建一个接口

    1. public interface ICustomService {
    2. void printf();
    3. }

    新建一个ICustomService的实现类

    1. @Service
    2. public class CustomServiceImpl implements ICustomService {
    3. public void printf() {
    4. }
    5. }

    再增加一个类不实现任何接口

    1. @Service
    2. public class CustomNoImpl {
    3. public void hello() {
    4. }
    5. }

    然后启动,可以ICustomService和CustomNoImpl看出AOP的代理使用的是CGLIB的动态代理

    然后我们通过application.properties配置将代理默认设置为JDK代理。

    spring.aop.proxy-target-class=false

        然后启动调试发现,CustomNoImpl因为没有实现接口,所以使用的是CGLIB生成的代理,而

    customService有接口实现,所以使用JDK的动态代理

    总结:JDK动态代理基于接口(必须声明接口并接口),CGLIB基于子类(可以只定义类)

  • 相关阅读:
    微信小程序源码合集8(iOS计算器+备忘录+仿今日头条+仿腾讯视频+艺术)
    【PTA题目】6-20 使用函数判断完全平方数 分数 10
    2023/09/10
    ESP32 Arduino引脚分配参考:您应该使用哪些 GPIO 引脚?
    第七章 将对象映射到 XML - 指定 XML 摘要
    5.Vectors Transformation Rules
    【牛客网刷题】(第三弹)链表与二分法oj
    多线程之ThreadPoolExecutor
    SpringBoot 集成 AKKA
    一文搞懂堆外内存(模拟内存泄漏)
  • 原文地址:https://blog.csdn.net/myli92/article/details/127586235