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

相关推荐
爱的叹息1 小时前
一个完整的 Spring Batch + RepositoryItemWriter + CrudRepository 示例,包含详细注释说明
windows·spring·batch
&白帝&1 小时前
Spring 框架中的 BeanUtils
java·python·spring
程序猿DD_12 小时前
如何用Spring AI构建MCP Client-Server架构
java·人工智能·后端·spring·架构
布朗克16815 小时前
应用服务接口第二次请求一直pending问题
java·spring·接口pending
工一木子15 小时前
Spring MVC 深度解析:原理、源码剖析与实战
java·后端·spring
爱的叹息15 小时前
Spring Batch ItemWriter 常见实现类及对比(含 RepositoryItemWriter)
java·spring·batch
Shaoxi Zhang1 天前
Spring学习笔记06——bean、java bean、spring bean、POJO几个概念讲解
java·学习·spring
Re2751 天前
springboot自动配置原理1--自动包规则原理
spring boot·spring
梅羽落1 天前
Spring笔记02-bean的生命周期
java·笔记·spring
中东大鹅1 天前
Spring MVC拦截器
java·spring·mvc