Spring AOP 中最推荐的方式是直接将注解作为通知方法参数自动注入,无需手动反射;需确保注解保留策略为 RUNTIME、切点表达式匹配且参数名类型一致。

在 Spring AOP 中,可以通过 JoinPoint 获取目标方法,再通过反射拿到其上的注解实例,从而读取注解的属性值。关键在于使用 joinPoint.getSignature() 定位到被代理的方法,再调用 getMethod().getAnnotation(XXX.class) 获取注解对象。
1. 定义自定义注解并声明属性
确保注解保留策略为 RUNTIME,且能用于方法上:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogOperation {
String value() default "";
int level() default 1;
boolean includeParams() default false;
}
2. 在切面中获取注解及属性值
在通知方法中,先判断目标方法是否标注了该注解,再安全地提取属性:
@Aspect
@Component
public class LoggingAspect {
@Around("@annotation(logOperation)")
public Object logExecutionTime(ProceedingJoinPoint joinPoint,
LogOperation logOperation) throws Throwable {
// 直接通过参数接收注解实例(Spring AOP 支持)
String value = logOperation.value();
int level = logOperation.level();
boolean includeParams = logOperation.includeParams();
System.out.printf("操作:%s,级别:%d,是否打印参数:%s%n",
value, level, includeParams);
return joinPoint.proceed();
}
}
✅ 这是最推荐的方式:Spring AOP 允许直接将匹配的注解作为通知方法的参数,自动注入,无需手动反射。
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
立即学习“Java免费学习笔记(深入)”;
3. 手动反射获取(备用方案)
若因某些原因无法直接传参(如使用 @Pointcut 复杂表达式未绑定),可手动反射获取:
- 通过
joinPoint.getSignature()强转为MethodSignature - 调用
getMethod()得到Method对象 - 再调用
method.getAnnotation(LogOperation.class)
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
LogOperation logOp = method.getAnnotation(LogOperation.class);
if (logOp != null) {
String desc = logOp.value();
// ...
}
4. 注意事项
- 注解必须在运行时可见(
@Retention(RUNTIME)) - 切点表达式要与注解类型一致,如
@annotation(com.example.LogOperation) - 若注解在接口方法上,而实现类被代理,需确保 Spring 使用的是 JDK 动态代理(面向接口)或开启
proxyTargetClass=true启用 CGLIB,否则可能获取不到实现类上的注解 - 多个同类注解不支持自动注入(Java 不允许重复注解,除非用
@Repeatable,此时需用getAnnotationsByType)
不复杂但容易忽略:只要注解在方法上、切点写对、参数名和类型匹配,Spring 就能自动注入注解实例——这是最简洁可靠的做法。

















