I'm using Spring 3.x, Java 6.
I have an @Around aspect with the following joinpoint:
@Around("execution(public * my.service.*.*Connector.*(..))")
So, I'm basically interested in intercepting all calls to public methods of classes with the class name ending with "Connector". So far so good.
Now, in my aspect I would like to access the actual argument names of the methods:
public doStuff(String myarg, Long anotherArg)
myarg and anotherArg
I understand that using:
CodeSignature signature = (CodeSignature)jointPoint.getSignature();
return signature.getParameterNames();
will actually work but only if I compile the code with the "-g" flag (full debug) and I would rather not do it.
Is there any other way to get access to that kind of runtime information.
Thanks L
Unfortunately you can't do this :-(. It is a well known limitation of JVM/bytecode - argument names can't be obtained using reflection, as they are not always stored in bytecode (in the contrary to method/class names).
As a workaround several frameworks/specification introduce custom annotations over arguments like
WebParam
(name
property) orPathParam
.For the time being all you can get without annotations is an array of values.
I am not sure if its a best way, but I added a Annotation on my method:
My Annotation:
And in the Aspect:
This is probably a hack but i did not want to compile with more options to get information. Anyways, its working well for me. Only downside is that i need to keep the names in annotation and method in sync.
In Java 8 there is a new compiler flag that allows additional metadata to be stored with byte code and these parameter names can be extracted using the Parameter object in reflection. See JDK 8 spec. In newer versions of hibernate org.springframework.core.ParameterNameDiscoverer uses this feature. To use it compile using
javac
with this flag:Access parameters using reflection's Parameter class.
Check the implementations of
org.springframework.core.ParameterNameDiscoverer
.Annotations like
@RequestParam
used by spring inspect the parameter name if novalue
is set. So@RequestParam String foo
will in fact fetch the request parameter named "foo". It uses theParameterNameDiscoverer
mechanism. I'm just not sure which of the implementations are used, by try each of them.The
LocalVariableTableParameterNameDiscoverer
reads the.class
and uses asm to inspect the names.So, it is possible. But make sure to cache this information (for example - store a parameter name in a map, with key = class+method+parameter index).
But, as it is noted in the docs, you need the debug information. From the docs of
@PathVariable
:So, if you really don't want to include that information, Tomasz Nurkiewicz's answer explains the workaround.