全面解析 Spring AOP 切入点表达式
大家好,我是钢板兽!
Spring AOP(面向切面编程)是我们日常开发中实现日志记录、权限控制、事务管理等功能的神器。而切入点表达式(Pointcut Expression)则是这个神器的“瞄准镜”——你想拦哪里,就靠它来精确定位!
本篇文章将带你全面了解 AOP 切入点表达式的写法、含义、常见用法、以及典型场景实战。
文章目录
- 全面解析 Spring AOP 切入点表达式
- 1.什么是切入点表达式?
- 2.切入点表达式详解
- 2.1`execution`:按方法签名匹配
- 2.2`within`:匹配某个类或包下的所有方法
- 2.3`@annotation`:匹配打了特定注解的方法
- 2.4 `args(...)`:匹配方法参数类型
- 2.5`@within` / `@target`:匹配类上的注解
- 2.6`bean(beanName)`:按 Bean 名称匹配
- 3.实战推荐组合用法
- 3.1全局统一增强(比如日志)
- 3.2 精准注解增强
- 4.表达式参考速查表
1.什么是切入点表达式?
切入点表达式是 Spring AOP 中用于描述增强逻辑应该作用在哪些方法上的一种匹配语法。
搭配 @Aspect
和 @Before
、@After
、@Around
等注解使用:
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("执行方法:" + joinPoint.getSignature().getName());
}
这条表达式的意思是:“匹配 com.example.service 包下所有类的所有方法”。
最常见的表达式是以 execution(...)
开头的,如:
execution(方法修饰符 返回值类型 包名.类名.方法名(参数))
参数可以使用通配符,表示“任意”或“全部”
2.切入点表达式详解
2.1execution
:按方法签名匹配
写法 | 含义 |
---|---|
execution(* com.example.service.UserService.*(..)) | 匹配 UserService 中所有方法 |
execution(public void com.example.service.UserService.createUser(..)) | 精确匹配某个方法 |
execution(* com.example..*Service.*(..)) | 匹配 com.example 包及其子包下所有以 Service 结尾的类的方法 |
execution(* *(..)) | 匹配所有方法(慎用!) |
*
表示任意..
表示任意层级包或任意参数
2.2within
:匹配某个类或包下的所有方法
@Within("com.example.service.UserService")
匹配该类的所有方法。
@Within("com.example.service..*")
匹配 service 包及其子包下所有类的方法。
2.3@annotation
:匹配打了特定注解的方法
@Before("@annotation(com.example.anno.Log)")
只拦截那些加了 @Log
注解的方法。
2.4 args(...)
:匹配方法参数类型
@Before("args(java.lang.String)")
匹配第一个参数为 String
类型的方法。
@Before("args(.., int)")
匹配最后一个参数是 int 的方法。
2.5@within
/ @target
:匹配类上的注解
@within(MyAnnotation)
:拦截被注解的类中的所有方法@target(MyAnnotation)
:和@within
类似,但作用在代理类上
2.6bean(beanName)
:按 Bean 名称匹配
@Before("bean(userService)")
只拦截 Bean 名为 userService
的方法,适合用于特定 Spring Bean 的增强。
3.实战推荐组合用法
3.1全局统一增强(比如日志)
@Aspect
@Component
public class LogAspect {
@Before("execution(* com.example.service..*.*(..))")
public void log(JoinPoint jp) {
System.out.println("[LOG] " + jp.getSignature());
}
}
3.2 精准注解增强
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Audit {
String value() default "";
}
// 切面类
@Aspect
@Component
public class AuditAspect {
@Before("@annotation(audit)")
public void audit(Audit audit) {
System.out.println("审计操作模块:" + audit.value());
}
}
// 业务方法
@Audit("用户模块")
public void updateUser(String name) { ... }
4.表达式参考速查表
表达式 | 描述 |
---|---|
execution(* com.example..*.*(..)) | 所有方法 |
@annotation(Log) | 有 @Log 注解的方法 |
within(com.example..*) | 指定包内的所有类的方法 |
args(String, ..) | 第一个参数是 String 的方法 |
bean(userService) | Bean 名为 userService 的对象的方法 |
如果这篇文章对你有帮助,欢迎点赞、转发、留言。
| 第一个参数是 String 的方法 |
| bean(userService)
| Bean 名为 userService 的对象的方法 |
如果这篇文章对你有帮助,欢迎点赞、转发、留言。
关注我带你学习更多Java后端开发的技术干货 !