踩坑实录!Spring AOP切点表达式失效之谜及高效修复攻略

在 Java 开发的广袤天地里,Spring AOP 想必是大家都十分熟悉的利器,它为我们的代码编织了一张强大的横切关注点之网,极大地提升了代码的可维护性和可扩展性。关于 Spring AOP 的常规使用方法,官方文档docs.spring.io/spring-fram...已经有了详尽的阐述,本文就不再赘述。今天,我们将聚焦于一次棘手的 Spring AOP 实战问题 ------ 切点表达式失效的排查与修复全过程,带你一探究竟,揭开其中的奥秘。为了让大家能够更直观地理解,我们将通过一个简单却典型的小例子来复现这一问题。

示例重现:问题初现

1、引入AOP依赖

在项目的pom.xml文件中,添加如下依赖,引入Spring AOP的核心功能:

xml 复制代码
  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

2、自定义注解

定义一个用于标识特定类型的注解,为后续的切面操作提供切入点:

less 复制代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ApiClient{
}

3、编写自定义切面

利用AspectJ的注解风格,创建一个切面类,尝试在目标对象执行方法前后进行自定义操作:

kotlin 复制代码
@Aspect
@Component
public class ApiClientAspect {
    
    @Around("@annotation(apiClient)")
    public Object around(ProceedingJoinPoint pjp, ApiClient apiClient){
        System.out.println("只是一个示例项目模拟,没有任何业务语义");
        try {
            return pjp.proceed();
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }

    }

}  

4、应用注解与测试

在一个RestController上添加我们自定义的注解,然后尝试通过浏览器访问该接口,期望看到切面逻辑生效的结果:

less 复制代码
@RestController
@RequestMapping("test")
@ApiClient
public class TestController {
    
    @GetMapping("hello")
    public String hello(){
        return "hello";
    }
}

5、意外状况:AOP未生效

然而,当我们兴致勃勃地通过浏览器访问TestController的接口时,却发现 AOP 的切面逻辑并没有按照预期执行,这无疑给我们的开发进程泼了一盆冷水。究竟是哪里出了问题呢?

抽丝剥茧:问题修复

经过一番深入排查和思考,我们发现问题的关键在于切点表达式的选择。将原来的切点表达式@annotation替换为@within后,AOP 切面逻辑终于如愿生效了。

深入探究:为何 @within能解决问题?

这背后的原理其实与切点表达式的作用域息息相关。不同的切点表达式有着各自独特的匹配规则,官方文档
docs.spring.io/spring-fram...

虽然有详细的说明,但为了方便大家快速了解,这里为你整理了常见切点表达式的含义及用途:

表达式类型 描述
execution 匹配方法切入点
within 匹配指定类型
this 匹配代理对象实例的类型
target 匹配目标对象实例的类型
args 匹配方法参数
bean 匹配 bean 的 id 或名称
@within 匹配类型是否含有注解
@target 匹配目标对象实例的类型是否含有注解
@annotation 匹配方法是否含有注解
@args 匹配方法参数类型是否含有注解

经验总结:避坑指南

本次问题的解决过程源于团队成员的一次求助,起初我也一时摸不着头脑,直到留意到注解是添加在类上而非方法上,才恍然大悟。这次小小的 "坑" 让我们深刻认识到了切点表达式的细节和作用域的重要性。希望通过分享这次经历,能帮助更多的开发者在使用 Spring AOP 时少走弯路,避免陷入同样的困境。

如果你对切点表达式的详细使用和更多高级特性感兴趣,不妨参考这篇优质博文
blog.csdn.net/weixin_4379...,相信你能从中获取更多有价值的信息。

相关推荐
萧瑟余晖8 小时前
Java深入解析篇十七之Spring Security
java·开发语言·spring
Flittly13 小时前
【雕虫大技】Agent 动态 Skill 供应链安全加固(二):执行隔离沙箱实战
java·spring boot·spring
BUG指挥官1 天前
Sa-Token和Spring Security对比
java·后端·spring
geminigoth1 天前
Spring AI Alibaba 入门开发一(备份)
java·人工智能·spring
xbgRS2 天前
spring整合mybaits
java·spring·mybatis
ruleslol2 天前
静态依赖注入 VS 动态依赖查询
spring
墨雨晨曦882 天前
Spring AI总结
java·人工智能·spring
用户3126874877202 天前
Spring Boot 异常处理到底怎么玩的?从 DispatcherServlet 到全局兜底的全链路拆解
spring
不才不才不不才2 天前
Spring 源码系列(17): HandlerMapping 与 HandlerAdapter 两大体系
java·后端·spring
(轻舟已过万重山)2 天前
第40章 Spring AI 实战:企业级 AI 应用架构
人工智能·spring·架构