Maple's Blog.

MethodSignature 详解

字数统计: 965阅读时长: 4 min
2025/11/25

非常好!这是一个紧跟上面 AOP 话题的深入问题。

MethodSignature 是 Spring AOP 中的一个核心接口,它提供了关于被增强(被拦截)方法的详细元信息

简单来说,当你的 Advice(如 @Around@Before)被执行时,Spring AOP 需要告诉你:“你现在正在拦截的是哪个方法?” —— MethodSignature 就是这个问题的详细答案。


核心理解

  1. 它是什么? 它是 Spring 对 Java 标准库 java.lang.reflect.Method 的扩展,不仅包含了 Method 本身,还包含了方法的返回值类型参数类型等完整的签名信息。
  2. 你在哪里能拿到它? 在 Advice 的方法参数中,通常是通过 JoinPoint(用于 @Before, @After 等)或 ProceedingJoinPoint(用于 @Around)来获取。
  3. 它有什么用? 让你在 Advice 内部能够动态地获取和操作当前正在执行的目标方法。

如何获取 MethodSignature

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import java.lang.reflect.Method;

@Aspect
@Component
public class MyAspect {

@Around("execution(* com.example.service.*.*(..))")
public Object myAdvice(ProceedingJoinPoint pjp) throws Throwable {
// 1. 从 ProceedingJoinPoint 获取 MethodSignature
MethodSignature signature = (MethodSignature) pjp.getSignature();

// 2. 现在你可以从 signature 中获取各种信息了
// ...

return pjp.proceed();
}
}

MethodSignature 的常用方法及用途

假设我们有一个目标方法:

1
2
3
public String UserService.findUserById(Long id, String name) {
// ...
}

当这个方法的 @Around Advice 执行时,我们可以通过 MethodSignature 获取以下信息:

方法 示例返回值 描述与用途
Method getMethod() public String UserService.findUserById(Long, String) 获取被拦截的 Method 对象本身。这是最核心的方法,可以用于进一步的反射操作。
Class getReturnType() String.class 获取方法的返回类型。常用于在 @Around Advice 中检查或修改返回值。
String getName() "findUserById" 获取方法名。常用于日志记录,记录是哪个方法被执行了。
Class[] getParameterTypes() [Long.class, String.class] 获取方法的参数类型数组。用于高级反射场景,比如判断参数类型。
String[] getParameterNames() ["id", "name"] 获取方法的参数名称数组非常有用! 可以让你通过参数名来获取具体的参数值。

一个完整的实战示例

让我们结合 ProceedingJoinPointMethodSignature 来创建一个强大的日志 Advice,它能打印出方法名、所有参数名和参数值,以及返回值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@Aspect
@Component
public class DetailedLoggingAspect {

@Around("execution(* com.example.service.*.*(..))")
public Object logMethodDetails(ProceedingJoinPoint pjp) throws Throwable {
// 1. 获取 MethodSignature
MethodSignature signature = (MethodSignature) pjp.getSignature();

// 2. 获取方法信息
String methodName = signature.getName();
Class<?> returnType = signature.getReturnType();

// 3. 获取参数名和参数值
String[] parameterNames = signature.getParameterNames();
Object[] args = pjp.getArgs();

// 4. 构建参数字符串
StringBuilder paramsBuilder = new StringBuilder();
for (int i = 0; i < parameterNames.length; i++) {
if (i > 0) {
paramsBuilder.append(", ");
}
paramsBuilder.append(parameterNames[i])
.append("=")
.append(args[i]);
}

System.out.println("【进入方法】方法名: " + methodName + " | 参数: [" + paramsBuilder.toString() + "] | 返回类型: " + returnType.getSimpleName());

try {
// 执行原方法
Object result = pjp.proceed();

// 打印返回值
System.out.println("【方法返回】方法名: " + methodName + " | 返回值: " + result);
return result;

} catch (Exception e) {
System.out.println("【方法异常】方法名: " + methodName + " | 异常: " + e.getMessage());
throw e;
}
}
}

执行上述 Advice,对于 findUserById(123L, "Alice") 的调用,控制台会输出:

1
2
【进入方法】方法名: findUserById | 参数: [id=123, name=Alice] | 返回类型: String
【方法返回】方法名: findUserById | 返回值: User{name='Alice', ...}

总结

  • MethodSignature 是 Spring AOP 中反射信息的载体。
  • 它让你在 Advice 中能够动态地、详细地了解当前正在执行的是哪个方法。
  • 通过它,你可以获取方法名、参数类型、参数名、返回值类型,甚至是 Method 对象本身。
  • 这使得 AOP Advice 变得非常灵活和强大,可以实现精细化的逻辑,如基于参数名的日志记录、动态权限检查(根据方法名或参数)、返回值包装等。
CATALOG
  1. 1. 核心理解
  2. 2. 如何获取 MethodSignature
  3. 3. MethodSignature 的常用方法及用途
  4. 4. 一个完整的实战示例
  5. 5. 总结