Reputation: 1055
In spring, it express the arg-names like this :
@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
}
In the doc , it says you may leave out the name of the parameter from the value of the "argNames" attribute. How can spring get argNames("bean,auditable") from anyPublicMethod?
Did java provide some api to get the parameter names?
I think it use the aspectJ to parse the expression, did aspectJ provide the feature?
Upvotes: 0
Views: 1461
Reputation: 149145
Just a complement to the other answers. Spring documentation is explicit : Spring does its best to retrieve correct parameters :
ajc
(aspectJ compiler) has been used)@Param
annotationsUpvotes: 0
Reputation: 136102
In Java 8 we can use reflection to get parameter name, see http://docs.oracle.com/javase/tutorial/reflect/member/methodparameterreflection.html. Though argument names will be present if the classes have been compiled with -g:vars
.
In earlier versions we need to use some tool, like 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);
}
prints
args
Upvotes: 2
Reputation: 280138
Your annotation
@Before(
value="com.xyz.lib.Pointcuts.anyPublicMethod() && target(bean) && @annotation(auditable)",
argNames="bean,auditable")
, assuming anyPublicMethod()
matches any public method, will match any public method annotated with whatever type a parameter named auditable
is and invoked on an object of bound to the parameter named bean
.
In your method, a parameter named auditable
is of type Auditable
, so this @Before
advice would match something like
public class SomeComponent {
@Auditable
public void someMethod() {}
}
I will bind the SomeComponent
type bean to the bean
parameter and the instance for the @Auditable
annotation to the auditable
parameter when invoking the advice.
Java does not have an API for getting parameter names. Parameter names are also not always present in the byte code. When they are, Spring uses the ASM library to parse the bytecode and retrieve them.
Upvotes: 0