Spring 4连接点获取方法参数名称和值

Deb*_*pam 10 spring spring-aop

我使用的是Spring 4.3.是否可以获取传递给它的方法参数名称和值?我相信这可以使用AOP(建议之前)完成,如果可能的话,请给我一个源代码.

sno*_*rbi 12

以下按预期工作(Java 8 + Spring 5.0.4 + AspectJ 1.8.13):

@Aspect
@Component
public class SomeAspect {

    @Around("@annotation(SomeAnnotation)")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        CodeSignature codeSignature = (CodeSignature) joinPoint.getSignature();

        System.out.println("First parameter's name: " + codeSignature.getParameterNames()[0]);
        System.out.println("First argument's value: " + joinPoint.getArgs()[0]);

        return joinPoint.proceed();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你想映射它 String[] names = codeSignature.getParameterNames(); Object[] args = joinPoint.getArgs(); Map<String, Object> fieldToValue = new HashMap<>(); for (int i = 0; i < names.length; i++) { fieldToValue.put(names[i], args[i]); } } (2认同)

sun*_*t84 5

CodeSignature methodSignature = (CodedSignature) joinPoint.getSignature();
String[] sigParamNames = codeSignature.getParameterNames(); 
Run Code Online (Sandbox Code Playgroud)

您可以获取方法签名参数名称。


Myk*_*nko 0

不幸的是,你不能这样做。这是字节码的一个众所周知的限制 - 参数名称无法使用反射获得,因为它们并不总是存储在字节码中。

作为解决方法,您可以添加其他注释,例如@ParamName(name = "paramName").

因此,您可以通过以下方式获取参数名称:

MethodSignature.getMethod().getParameterAnnotations()
Run Code Online (Sandbox Code Playgroud)

更新

从 Java 8 开始你可以这样做

您可以使用 java.lang.reflect.Executable.getParameters 方法获取任何方法或构造函数的形参名称。(类 Method 和 Constructor 扩展了类 Executable,因此继承了方法 Executable.getParameters。)但是,.class 文件默认情况下不存储形式参数名称。这是因为许多生成和使用类文件的工具可能不希望包含参数名称的 .class 文件具有更大的静态和动态占用空间。特别是,这些工具必须处理更大的 .class 文件,并且 Java 虚拟机 (JVM) 将使用更多内存。此外,某些参数名称(例如秘密或密码)可能会暴露有关安全敏感方法的信息。

要将形式参数名称存储在特定的 .class 文件中,从而使 Reflection API 能够检索形式参数名称,请使用 javac 编译器的 -parameters 选项来编译源文件。

https://docs.oracle.com/javase/tutorial/reflect/member/methodparameterreflection.html