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

时间:2014-07-29 02:20:06

标签: java spring aspectj

春天,它表达了这样的arg-names:

@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是否提供了这个特性?

3 个答案:

答案 0 :(得分:2)

在Java 8中,我们可以使用反射来获取参数名称,请参阅http://docs.oracle.com/javase/tutorial/reflect/member/methodparameterreflection.html。虽然如果类已使用-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

答案 1 :(得分:0)

您的注释

@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库来解析字节码并检索它们。

答案 2 :(得分:0)

只是对其他答案的补充。 Spring文档是显式的:Spring尽力检索正确的参数:

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