首页 > 其他分享 >AOP失效场景总结

AOP失效场景总结

时间:2024-09-14 16:16:24浏览次数:11  
标签:场景 Spring 代理 调用 切面 AOP 失效 方法

AOP(面向切面编程)在 Spring 中是通过动态代理机制来实现的,但在某些情况下,AOP 可能会失效。以下是常见的几种 AOP 失效的场景及原因:

1. 内部方法调用

  • 原因:当类中的一个方法调用同一个类中的另一个方法时,AOP 不会生效。
  • 解释:Spring AOP 是基于代理的实现,只有通过代理对象调用方法时,切面才会生效。但在类的内部方法调用时,Spring 不会使用代理对象,而是直接通过 this 引用调用方法,因此切面不会被触发。
  • 解决方法:通过外部类或依赖注入调用该方法,确保调用经过代理对象。

示例:

public class MyService {
  // This method has an aspect public
  void methodA() {
    methodB(); // This internal call will not trigger AOP
  }
  public void methodB() {
    // Some logic
  }
}

 

2. 代理类类型错误

  • 原因:如果类没有实现接口并且没有使用 CGLIB 代理,AOP 可能不会生效。
  • 解释:Spring AOP 默认使用 JDK 动态代理,它仅对接口生成代理类。如果目标类没有实现接口,Spring 则无法使用 JDK 动态代理,因此 AOP 会失效。此时需要通过 CGLIB 代理生成子类来支持非接口的类。
  • 解决方法:确保类实现接口,或配置 Spring 使用 CGLIB 代理。

配置 CGLIB 代理示例:

@Configuration 
@EnableAspectJAutoProxy(proxyTargetClass = true) 
// 强制使用 CGLIB 代理 
public class AppConfig { 
}

3. 使用 final 修饰的方法或类

  • 原因:AOP 代理机制无法拦截 final 方法或类。
  • 解释:CGLIB 通过生成子类来实现代理,如果某个类或方法被声明为 final,CGLIB 无法对其进行代理。因此,AOP 不会生效。
  • 解决方法:避免使用 final 修饰需要被拦截的方法或类。

4. AOP 作用于 private 方法

  • 原因:AOP 不能拦截 private 方法。
  • 解释:AOP 依赖代理机制,而代理对象无法访问目标类的 private 方法。因此,切面不会生效。
  • 解决方法:将方法的访问修饰符改为 publicprotecteddefault

示例:

public class MyService { 
    @MyAspect
    private void myPrivateMethod() { 
        // AOP will not apply here 
    } 
}

5. 未使用 Spring 管理的对象

  • 原因:AOP 只能对 Spring 容器管理的 Bean 生效,如果一个对象没有被 Spring 容器管理,AOP 将不会生效。
  • 解释:Spring AOP 是通过 Spring 容器对 Bean 进行代理和管理的,如果直接通过 new 关键字创建对象,而不是通过 Spring 容器获取 Bean,该对象不会被代理,切面也不会被应用。
  • 解决方法:确保使用 @AutowiredApplicationContext.getBean() 从 Spring 容器中获取 Bean。

6. 目标方法为 static 方法

  • 原因:AOP 无法拦截 static 方法。
  • 解释:Spring AOP 是基于代理机制的,而代理对象只能代理实例方法,不能代理类的 static 方法。因此,静态方法不能应用 AOP。
  • 解决方法:避免在静态方法上使用 AOP,或将逻辑移至实例方法。

7. 切面未正确配置

  • 原因:如果切面没有正确地配置,AOP 可能不会生效。
  • 解释:切面需要通过注解(如 @Aspect)或 XML 文件进行声明,并通过 @EnableAspectJAutoProxy 或相应配置来启用 AOP。如果这些配置不正确,切面将不会生效。
  • 解决方法:确保切面类使用了 @Aspect 注解,项目中启用了 @EnableAspectJAutoProxy,并且切入点表达式正确。

示例:

@Aspect 
public class MyAspect { 
    @Before("execution(* com.example.MyService.*(..))") 
    public void beforeMethod() { 
        // Pre-processing logic 
    } 
}
 

8. 切入点表达式错误

  • 原因:切入点表达式不正确或没有匹配到目标方法。
  • 解释:如果定义的切入点表达式不精确或不匹配目标方法,切面不会生效。
  • 解决方法:仔细检查切入点表达式,确保其能够匹配到目标方法。

9. 未启用 AOP

  • 原因:未在配置类或 XML 文件中启用 AOP 支持。
  • 解释:Spring AOP 需要通过 @EnableAspectJAutoProxy 注解或 XML 配置启用。如果未启用,AOP 切面将不会生效。
  • 解决方法:在配置类中添加 @EnableAspectJAutoProxy,或在 XML 配置中启用 AOP。

示例:

@Configuration 
@EnableAspectJAutoProxy 
public class AppConfig { 
}

10. 直接使用代理对象的 this 调用

  • 原因:通过代理对象的 this 调用不会经过代理,而是直接调用方法,导致 AOP 失效。
  • 解释:Spring AOP 基于代理对象,当使用 this 调用时,实际调用的是目标对象的原始方法,而不是代理对象的增强方法。
  • 解决方法:避免使用 this 调用方法,确保方法调用经过代理。

总结

AOP 在以下情况下可能会失效:

  1. 内部方法调用时不经过代理对象。
  2. 目标类没有实现接口且未启用 CGLIB 代理。
  3. 方法或类被 final 修饰。
  4. 方法被声明为 private
  5. 目标对象不是由 Spring 容器管理。
  6. 切入点表达式不匹配目标方法。
  7. 未正确启用 AOP 支持。
  8. 切面没有正确配置或切入点表达式错误。
  9. 直接使用 this 调用代理对象的方法。

为避免这些问题,需要确保代理机制生效、配置正确、并且遵循 Spring AOP 的使用规则。

 

标签:场景,Spring,代理,调用,切面,AOP,失效,方法
From: https://www.cnblogs.com/Oct16/p/18414230

相关文章

  • 使用@Validated校验List集合中数据失效
    我们可以写一个集合实现list,代码如下,在controller类上面不用加@Validated注解,在controller使用自定义ValidableList集合,对list进行封装,就可以对scheduleDtoList做参数校验处理。@Api(tags="xxxx管理")@RestController@RequestMapping("aaa/indicatorDeviceCategoryDe......
  • 没想到一个 HTTP Client 居然考虑这么多场景...
    在项目开发过程中,HTTP请求可以说是非常常见的需求,无论是与外部API交互,还是实现微服务间的通信。这篇文章以Go语言为背景,探讨HTTP客户端的构建。Go的标准库net/http虽然功能强大,但在进行复杂的HTTP请求时,往往需要开发者写很多重复代码。在这种情况下,开发者就需要一个既......
  • 参数绑定在PHP代码测试中的重要作用与应用场景
    在PHP代码测试过程中,参数绑定起着至关重要的作用。它不仅能够提高代码的安全性,还能够优化性能,减少常见的错误。因此,了解参数绑定的作用以及其应用场景,对于开发者来说十分重要。参数绑定主要的作用之一就是防止SQL注入。SQL注入是数据库安全中常见的攻击方式之一,攻击者通过在SQL语......
  • 选择困难症必看!从功能到应用场景,TAPD与禅道全面对比指南
    在当今这个信息化、数字化的时代,项目管理工具已经成为企业提升效率、优化流程、加强团队协作的必备神器。而在众多项目管理工具中,TAPD(腾讯敏捷产品开发平台)和禅道(Zentao)无疑是两款备受瞩目的佼佼者。它们各自拥有独特的功能和优势,适用于不同的应用场景。那么,面对这两款优秀的......
  • 【linux】centos7不支持更新后,yum源失效问题!
    1、yum安装时提示该错误。Couldnotretrievemirrorlisthttp://mirrorlist.centos.org/?release=7&arch=aarch64&repo=os&infra=stockerrorwas14:curl#6-"Couldnotresolvehost:mirrorlist.centos.org;未知的错误"原因:yum源官方不支持更新了,要换源2、先备份源mv/e......
  • 拨号VPS与代理IP有什么不同?两者的应用场景有哪些
    在数字化时代,无论是个人用户还是企业,都需要高效且安全的网络访问手段来应对日益复杂的网络环境。拨号VPS(VirtualPrivateServer)和代理IP是两种常用的网络工具,它们在提供动态IP、隐藏真实IP地址、提升网络访问效率和安全性方面扮演着重要角色。本文将深入解析拨号VPS与代理IP的概念......
  • YOLOv9改进策略【损失函数篇】| 引入Soft-NMS,提升密集遮挡场景检测精度,包括GIoU-NMS、
    一、背景:传统的非极大值抑制(NMS)算法在目标检测中存在一个问题,即当一个物体的检测框与具有最高得分的检测框M有重叠(在预定义的重叠阈值内)时,会将该检测框的得分设置为零,从而导致该物体可能被遗漏,降低了平均精度。为了解决这个问题,作者提出了Soft-NMS算法。本文将YOLOv9默认......
  • Whisper 模型在实时语音转录中有哪些具体的应用场景?
    关注我,持续分享逻辑思维&管理思维&面试题;可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导;推荐专栏《10天学会使用asp.net编程AI大模型》,目前已完成所有内容。一顿烧烤不到的费用,让人能紧跟时代的浪潮。从普通网站,到公众号、小程序,再到AI大模型网站。干货满满。学成后可......
  • @Transactional 注解使用场景
    我把这些事务问题归结成了三类:不必要、不生效、不回滚,接下用一些demo演示下各自的场景。不必要1.无需事务的业务在没有事务操作的业务方法上使用@Transactional注解,比如:用在仅有查询或者一些HTTP请求的方法,虽然加上影响不大,但从编码规范的角度来看还是不够严谨,建议去掉。@Tran......
  • swiper6版本下滚轮失效&分页失效等的问题
    swiper6中一些配置会失效原因是控件需要单独引入 如我这次用的swiper相关版本是: [email protected]@4.1.1 在滚轮切换、分页、左右切换和动效配置中,都需要单独引入控件 import{Swiper,SwiperSlide}from"vue-awesome-swiper";importSw......