MethodSignature signature = (MethodSignature) joinPoint.getSignature()
// 1. 使用 Signature(通用信息)
Signature signature1 = joinPoint.getSignature();
System.out.println("方法名:" + signature1.getName()); // 可用
System.out.println("所属类:" + signature1.getDeclaringTypeName()); // 可用
// System.out.println("返回值类型:" + signature1.getReturnType()); // 报错!Signature 没有该方法// 2. 使用 MethodSignature(方法特有信息)
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
System.out.println("方法名:" + signature.getName()); // 继承自 Signature
System.out.println("返回值类型:" + signature.getReturnType()); // 特有方法
System.out.println("参数类型:" + Arrays.toString(signature.getParameterTypes())); // 特有方法
Method method = signature.getMethod(); // 获取 Method 对象(可操作注解等)
- 强制转换为
MethodSignature
时,必须确保连接点是方法执行(Spring AOP 中默认都是方法连接点),否则会抛出ClassCastException
。 - 在 Spring AOP 中,几乎所有场景都是方法连接点,因此实际开发中常用
MethodSignature
来获取更详细的方法信息。
一
Signature
是顶层接口,代表连接点的签名信息,适用于所有类型的连接点(如方法调用、构造方法、字段访问等)。MethodSignature
是Signature
的子接口,专门用于方法类型的连接点,仅在连接点是方法执行时有效。
2. 可获取的信息差异
Signature
接口提供通用的签名信息,而 MethodSignature
在此基础上增加了方法特有的信息:
Signature 提供的信息(通用) | MethodSignature 额外提供的信息(方法特有) |
---|---|
- 方法名(String getName() ) | - 方法参数类型(Class<?>[] getParameterTypes() ) |
- 所属类名(String getDeclaringTypeName() ) | - 方法返回值类型(Class<?> getReturnType() ) |
- 所属类(Class<?> getDeclaringType() ) | - 方法对象(Method getMethod() ) |
3. 使用场景
Signature signature1 = joinPoint.getSignature()
适用于不确定连接点类型的场景(虽然 Spring AOP 主要处理方法,但理论上可能有其他类型连接点)。只能获取通用信息(如方法名、类名),无法直接获取方法参数类型、返回值类型等细节。MethodSignature signature = (MethodSignature) joinPoint.getSignature()
仅适用于方法类型的连接点(Spring AOP 中最常见的场景)。通过强制转换,可以获取方法特有的详细信息,例如:- 方法的参数类型(用于参数校验、日志打印等)
- 方法的返回值类型(用于结果处理)
- 直接获取
Method
对象(可反射调用、获取注解等)
@Component
@Aspect //告诉Spring这个组件是个切面。
public class LogAspect {@Pointcut("execution(int com.atguigu.spring.aop.calculator.MathCalculator.*(..))")public void pointCut(){};@Before("pointCut()")public void logStart(JoinPoint joinPoint){//1、拿到方法全签名MethodSignature signature = (MethodSignature) joinPoint.getSignature();//方法名String name = signature.getName();//目标方法传来的参数值Object[] args = joinPoint.getArgs();System.out.println("【切面 - 日志】【"+name+"】开始:参数列表:【"+ Arrays.toString(args) +"】");}@After("pointCut()")public void logEnd(JoinPoint joinPoint){MethodSignature signature = (MethodSignature) joinPoint.getSignature();String name = signature.getName();System.out.println("【切面 - 日志】【"+name+"】后置...");}@AfterReturning(value = "pointCut()",returning = "result") //returning="result" 获取目标方法返回值public void logReturn(JoinPoint joinPoint,Object result){MethodSignature signature = (MethodSignature) joinPoint.getSignature();String name = signature.getName();System.out.println("【切面 - 日志】【"+name+"】返回:值:"+result);}@AfterThrowing(value = "pointCut()",throwing = "e" //throwing="e" 获取目标方法抛出的异常)public void logException(JoinPoint joinPoint,Throwable e){MethodSignature signature = (MethodSignature) joinPoint.getSignature();String name = signature.getName();System.out.println("【切面 - 日志】【"+name+"】异常:错误信息:【"+e.getMessage()+"】");}//参数带什么就切
// @Before("args(int,int)")public void haha(){System.out.println("【切面 - 日志】哈哈哈...");}//参数上有没有标注注解
// @Before("@args(com.atguigu.spring.aop.annotation.MyAn) && within(com.atguigu.spring.aop.service.UserService)")public void hehehe(){System.out.println("【切面 - 日志】呵呵呵...");}//方法上
// @Before("@annotation(com.atguigu.spring.aop.annotation.MyAn)")public void test(){System.out.println("【切面 - 日志】MyAn测试...");}}