踩坑实录!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...,相信你能从中获取更多有价值的信息。

相关推荐
文哥打酱油41 分钟前
flowable对已经部署的流程进行更新,不产生新版本
java·后端·spring·flowable
麦兜*1 小时前
【HTTP】防XSS+SQL注入:自定义HttpMessageConverter过滤链深度解决方案
java·网络·spring boot·sql·spring·http·xss
linmoo19863 小时前
Spring AI 系列之二十八 - Spring AI Alibaba-基于Nacos的prompt模版
人工智能·spring·nacos·prompt·springai·springaialibaba·动态提示词
程序员良辰7 小时前
Spring与SpringBoot:从手动挡到自动挡的Java开发进化论
java·spring boot·spring
鹦鹉0077 小时前
SpringAOP实现
java·服务器·前端·spring
星月昭铭11 小时前
Spring AI调用Embedding模型返回HTTP 400:Invalid HTTP request received分析处理
人工智能·spring boot·python·spring·ai·embedding
没有bug.的程序员13 小时前
《Spring Security源码深度剖析:Filter链与权限控制模型》
java·后端·spring·security·filter·权限控制
lang2015092814 小时前
如何使用 Apache Ignite 作为 Spring 框架的缓存(Spring Cache)后端
spring·缓存·apache·ignite
星月昭铭16 小时前
Spring AI集成Elasticsearch向量检索时filter过滤失效问题排查与解决方案
人工智能·spring boot·spring·elasticsearch·ai
巴厘猫18 小时前
拥抱智能时代:Spring AI:在Spring生态中构建AI应用——深度剖析与实践
java·spring