Java中 Spring @Pointcut("@annotation(...)") 怎么配置方法级别的自定义注解切点
发布于2026-07-15 阅读(0)
### 使用 `@Pointcut("@annotation(全限定类名)")` 精准拦截方法级注解
先说一个核心要点:直接使用 `@Pointcut("@annotation(全限定类名)")` 就能精准拦截加了该注解的方法。关键在于,注解定义、切面写法以及包路径设置三个方面,都绝对不能出错。
*(此处为原文提供的图片,说明配置方法级别自定义注解切点的效果)*
### 注解定义必须带上正确的元注解
自定义注解如果想让 AOP 识别,必须明确声明它的作用范围和生命周期,否则根本不会被 AOP 机制捕获到。具体需要留意以下几点:
- `@Target(ElementType.METHOD)`:告诉这个注解只能标注在方法上。如果还想支持类级别的注解,可以加上 `ElementType.TYPE`。
- `@Retention(RetentionPolicy.RUNTIME)`:这个必须是运行时保留。Spring AOP 在运行期要靠反射来读取注解信息,如果生命周期设错了,拦截就会落空。
- `@Documented`(可选):主要是给生成 Ja vaDoc 用的,对 AOP 没有影响。
- `@Inherited`(一般不用):注解本身不会继承给子类,AOP 也不依赖它。
来看一个典型的自定义注解定义:
```ja va
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
String value() default "";
}
```
### 切点表达式的写法必须精确
使用 `@annotation` 切点时,括号里填的一定是注解的**全限定类名**,也就是包路径加类名,而不是简单的类名。这一点非常关键,弄错了就会匹配不上。
- ✅ 正确写法:`@Pointcut("@annotation(cn.zhy.annotation.Log)")`
- ❌ 错误写法:`@Pointcut("@annotation(Log)")` 或者 `@Pointcut("@annotation(log)")`
这个表达式只认被 `@Log` 这个注解明确标记过的方法,不管这个方法是在 Controller、Service 还是普通工具类里面,它都认。但如果是类上的注解间接导致方法被拦截,这种场景就照顾不到了。
### 切面类必须启用并正确引用通知
切面类本身需要被 Spring 管理,通知方法也要正确引用切点方法名。这里有几个细节需要注意:
- 给类加上 `@Component` 和 `@Aspect` 注解,这样 Spring 才能把它当成一个切面来管理。
- `@Pointcut` 方法建议用 `private` 修饰,它只是一个表达式的载体,不需要也不执行具体的业务逻辑。
- 通知方法(比如 `@Before`、`@After` 等)中直接写切点方法名即可,比如 `"logPointcut()"`,没必要再重复写一遍表达式。
示例代码:
```ja va
@Component
@Aspect
public class LogAspect {
@Pointcut("@annotation(cn.zhy.annotation.Log)")
private void logPointcut() {}
@Before("logPointcut()")
public void doBefore(JoinPoint joinPoint) {
System.out.println("方法 " + joinPoint.getSignature().getName() + " 开始执行");
}
}
```
### 实际使用时只需要在目标方法上加注解
一旦配置完成,实际使用时非常简单——在需要被拦截的方法上直接标注 `@Log` 注解。无论是 Controller、Service 还是 Utils 类里的方法,都会被自动拦截。
```ja va
@RestController
public class UserController {
@Log("用户查询操作")
@GetMapping("/user/{id}")
public User getById(@PathVariable Long id) {
return userService.findById(id);
}
}
```
启动应用后调用该接口,控制台会打印出前置日志。整个过程不需要修改方法签名,也不需要在业务代码中嵌入任何侵入性的逻辑。
总而言之,配置过程并不复杂,但注解的定义、切点表达式中的全限定类名、以及切面类的正确启用,这三个环节任何一个出错都会导致拦截失败。只要把握住这几个关键点,就能轻松实现方法级别的自定义注解切点。
本文转载于:https://www.php.cn/faq/2823093.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。