AOP 的织入过程是怎样的?

AOP(面向切面编程)的织入(Weaving)是将切面(Aspect)应用到目标对象(Target Object)并创建代理对象(Proxy Object)的过程。这个过程可以发生在不同的阶段,Spring 支持以下几种织入方式:

1. 编译时织入(Compile-time Weaving):

  • 原理: 在编译 Java 源代码时,直接将切面代码插入到目标类中,生成修改后的字节码。
  • 实现: 需要特殊的编译器,例如 AspectJ 编译器(ajc)。
  • 优点:
    • 性能最好,因为在运行时不需要额外的处理。
    • 可以在编译时进行更全面的检查和优化。
  • 缺点:
    • 需要特殊的编译器,配置较为复杂。
    • 不适用于已经编译好的第三方库。

2. 类加载时织入(Load-time Weaving,LTW):

  • 原理: 在 Java 虚拟机(JVM)加载类时,通过类加载器(Class Loader)动态地修改目标类的字节码,将切面代码织入。
  • 实现:
    • AspectJ LTW: 使用 AspectJ 提供的 LTW 代理。
    • Spring 提供的 LTW: 使用 Spring 提供的 LoadTimeWeaver 接口和相关的配置。
  • 优点:
    • 不需要修改源代码或使用特殊编译器。
    • 可以对第三方库进行织入。
  • 缺点:
    • 需要在 JVM 启动时配置 LTW 代理,配置较为复杂。
    • 性能比编译时织入略差。

3. 运行时织入(Runtime Weaving):

  • 原理: 在运行时,通过动态代理技术创建目标对象的代理对象,将切面逻辑织入到代理对象中。
  • 实现:
    • JDK 动态代理: 基于接口的代理,要求目标对象必须实现至少一个接口。
    • CGLIB 动态代理: 基于类的代理,通过生成目标类的子类来实现代理,不需要目标对象实现接口。
    • Spring AOP 默认使用 JDK 动态代理,如果目标对象没有实现接口,则使用 CGLIB 动态代理。
  • 优点:
    • 配置简单,使用方便。
    • 不需要修改源代码或使用特殊编译器。
  • 缺点:
    • 性能比编译时织入和类加载时织入略差。
    • JDK 动态代理只能对接口进行代理,无法对类进行代理。

Spring AOP 的织入过程(运行时织入):

Spring AOP 默认使用运行时织入,其织入过程如下:

  1. 解析配置: Spring 容器启动时,会解析 AOP 配置(XML 配置、@AspectJ 注解等),识别切面(Aspect)、切点(Pointcut)和通知(Advice)。
  2. 创建目标对象: 当 Spring 容器创建目标对象时,会检查目标对象是否匹配任何切点。
  3. 创建代理对象: 如果目标对象匹配某个切点,Spring 会为目标对象创建一个代理对象:
    • JDK 动态代理: 如果目标对象实现了接口,Spring 使用 JDK 动态代理创建代理对象。代理对象实现了与目标对象相同的接口,并将所有方法调用委托给一个 InvocationHandler
    • CGLIB 动态代理: 如果目标对象没有实现接口,Spring 使用 CGLIB 动态代理创建代理对象。代理对象是目标对象的子类,它重写了目标对象的方法。
  4. 织入通知: Spring 将通知(Advice)织入到代理对象中。
    • JDK 动态代理: InvocationHandler 负责在调用目标方法前后执行相应的通知。
    • CGLIB 动态代理: 在代理对象重写的方法中,调用相应的通知。
  5. 返回代理对象: Spring 容器将代理对象返回给应用程序,而不是目标对象本身。
  6. 方法调用: 当应用程序调用代理对象的方法时,代理对象会根据配置的通知类型(前置通知、后置通知、环绕通知等),在调用目标方法前后执行相应的通知逻辑。

总结:

AOP 的织入方式有多种,包括编译时织入、类加载时织入和运行时织入。Spring AOP 默认使用运行时织入,通过 JDK 动态代理或 CGLIB 动态代理创建目标对象的代理对象,并将切面逻辑织入到代理对象中。运行时织入的优点是配置简单、使用方便,缺点是性能略差。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰糖心书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值