Java spring如何从方法中获取args名称

Java spring如何从方法中获取args名称,java,spring,aspectj,Java,Spring,Aspectj,在spring中,它表示arg名称,如下所示: @Before( value="com.xyz.lib.Pointcuts.anyPublicMethod() && target(bean) && @annotation(auditable)", argNames="bean,auditable") public void audit(JoinPoint jp, Object bean, Auditable auditable) { AuditCode c

在spring中,它表示arg名称,如下所示:

@Before(
value="com.xyz.lib.Pointcuts.anyPublicMethod() && target(bean) && @annotation(auditable)",
argNames="bean,auditable")
public void audit(JoinPoint jp, Object bean, Auditable auditable) {
    AuditCode code = auditable.value();
// ... use code, bean, and jp
}
在文档中,它表示可以从“argNames”属性的值中省略参数的名称。spring如何从anyPublicMethod获取argNames(“bean,auditable”)

java是否提供了一些api来获取参数名

我认为它使用aspectJ来解析表达式,aspectJ是否提供了该功能?

您的注释

@Before(
value="com.xyz.lib.Pointcuts.anyPublicMethod() && target(bean) && @annotation(auditable)",
argNames="bean,auditable")
,假设
anyPublicMethod()
匹配任何公共方法,则将匹配使用名为
auditable
的参数所注释的任何类型的公共方法,并在绑定到名为
bean
的参数的对象上调用该方法

在您的方法中,名为
auditable
的参数属于
auditable
类型,因此此
@Before
建议将与以下内容匹配

public class SomeComponent {
    @Auditable
    public void someMethod() {}
}
调用通知时,我将
SomeComponent
类型bean绑定到
bean
参数,并将
@Auditable
注释的实例绑定到
Auditable
参数


Java没有获取参数名的API。参数名称也不总是出现在字节码中。如果是,Spring将使用ASM库解析字节码并检索它们

在Java 8中,我们可以使用反射来获取参数名,请参阅。但是,如果类是使用
-g:vars
编译的,则会出现参数名

在早期版本中,我们需要使用一些工具,如Javassist:

public static void main(String[] args) throws Exception {
    ClassPool pool = ClassPool.getDefault();
    CtClass c = pool.get("test.Test");
    CtMethod m = c.getDeclaredMethod("main");
    MethodInfo methodInfo = m.getMethodInfo();
    LocalVariableAttribute t = (LocalVariableAttribute) methodInfo.getCodeAttribute().getAttribute(javassist.bytecode.LocalVariableAttribute.tag);
    int i = t.nameIndex(0); 
    String v = methodInfo.getConstPool().getUtf8Info(i);
    System.out.println(v); 
}
印刷品

args

只是对其他答案的补充。Spring文档非常明确:Spring尽最大努力检索正确的参数:

  • 如果使用Java8,则使用Java8反射
  • 如果类是在调试模式下编译的,则参数名存在,spring使用它,如果使用了
    ajc
    (aspectJ编译器),则相同)
  • 它最终可以使用
    @Param
    注释
  • 如果不含糊,则使用该类型

我认为它使用了在方法中传递的参数的名称。