AspectJMethodPointcut不适合读取注解,因其仅支持静态方法签名匹配,不提供运行时反射环境;应改用AnnotationMatchingPointcut或在Advice中通过JoinPoint.getMethod()反射获取注解。

Spring 的 AspectJMethodPointcut 本身不直接提供反射读取目标方法注解的能力,它主要用于匹配方法签名(如类名、方法名、参数类型等),属于静态切入点判断机制。真正需要读取运行时注解(比如 @Transactional、自定义注解),应在通知(Advice)中通过反射获取目标方法对象,再调用 getMethod().getAnnotation(...)。
为什么 AspectJMethodPointcut 不适合读取注解
AspectJMethodPointcut 继承自 StaticMethodMatcherPointcut,其 matches(Method, Class) 方法只接收 Method 和目标类类型,但该 Method 是编译期确定的桥接方法或原始声明方法,且在匹配阶段尚未绑定具体代理对象或真实调用上下文;更重要的是,它不暴露反射所需的完整执行环境(如实际被代理的目标实例、真实的调用 Method 对象),也不支持在匹配时做注解扫描——因为注解读取依赖 JVM 的运行时保留策略(@Retention(RetentionPolicy.RUNTIME)),而匹配过程是静态的、无反射执行的。
正确做法:在 Advice 中通过 JoinPoint 获取 Method 并反射读取
要在切面中读取目标方法上的注解,应使用 JoinPoint(或更精确的 MethodSignature)获取真实的方法对象,再调用反射 API:
- 在
@Around、@Before等通知方法参数中声明JoinPoint joinPoint - 将
joinPoint.getSignature()强转为MethodSignature - 调用
methodSignature.getMethod()得到java.lang.reflect.Method - 用
method.getAnnotation(YourAnnotation.class)获取注解实例
示例:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
@Around("@annotation(org.springframework.transaction.annotation.Transactional)")
public Object checkTransactionAnnotation(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Transactional txAnn = method.getAnnotation(Transactional.class);
if (txAnn != null) {
System.out.println("Propagation: " + txAnn.propagation());
}
return joinPoint.proceed();
}
注意代理模式对 Method 反射的影响
Spring AOP 默认使用 JDK 动态代理(接口代理)或 CGLIB(类代理)。无论哪种方式,joinPoint.getSignature().getMethod() 返回的都是目标类中声明的方法对象(即原始方法),不是代理生成的桥接方法,因此能正确读取其上的注解。但需确保:
- 自定义注解必须声明
@Retention(RetentionPolicy.RUNTIME) - 注解需加
@Target({ElementType.METHOD, ElementType.TYPE})(若要支持类级别也需包含 TYPE) - 避免在接口上声明注解而实现类未继承(JDK 代理下,接口方法上的注解可被读取;CGLIB 下优先查实现类,接口注解不会自动继承)
如果非要扩展 Pointcut 做注解匹配,可用 AnnotationMatchingPointcut
Spring 提供了更合适的工具:AnnotationMatchingPointcut,它专为按注解匹配设计,内部已封装反射逻辑:
- 匹配类上注解:
AnnotationMatchingPointcut.forClassAnnotation(MyClassAnno.class) - 匹配方法上注解:
AnnotationMatchingPointcut.forMethodAnnotation(MyMethodAnno.class) - 可组合使用:
ComposablePointcut.and(...)
它底层会检查方法是否被指定注解标记(通过反射),比手动写 AspectJMethodPointcut 子类更安全、标准。

















