Java AOP JoinPoint does not get parameter names

ork picture ork · Aug 10, 2014 · Viewed 11.4k times · Source


I'm using Java Spring Mvc and Spring AOP to find the parameter names from the user.
I have a controller which get parameters from user and call a service.
I have an aspect that running before the service.
The aspect should check if username and apiKey parameters are exist.
Here is my code :

Controller :

@RequestMapping(method = RequestMethod.POST, produces=MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody String getDomainWithFoundIn(@RequestParam (value="domain") String domain, @RequestParam (value="user") String user, @RequestParam (value="apiKey") String apiKey) throws JsonGenerationException, JsonMappingException, IOException {
    return domainService.getDomainDataWithFoundIn(domain, user, apiKey);
}

Domain Service Interface :

public interface IDomainService {
    public String getDomainDataWithFoundIn(String domainStr, String user, String apiKey);
}

DomainService :

@Override
@ApiAuthentication
public String getDomainDataWithFoundIn(String domainStr, String user, String apiKey) {
//Do stuff here
}

And my AOP class :

@Component
@Aspect
public class AuthAspect {
@Before("@annotation(apiAuthentication)") 
public void printIt (JoinPoint joinPoint, ApiAuthentication apiAuthentication) throws NoAuthenticationParametersException, UserWasNotFoundException {
        final MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        final String[] parameterNames = signature.getParameterNames();
        **//parameterNames is null here.**
}

In this case, I'd expect to get on my aspect the "domain", "user" and "apiKey" parameter names.
Any idea what am i missing here ?
Thanks,
Or.

Answer

Lukasz Frankowski picture Lukasz Frankowski · Oct 31, 2014

As I've said in above comment, depending on proxy type you can or can't have access to parameter names. If your bean implements interface, the JDK proxy will be created by spring, and in this kind of proxy MethodSignature.getParameterNames() is null. If your bean doesn't implement interface, CGLIB proxy is created, where MethodSignature.getParameterNames() is filled.

If you can, you may switch to CGLIB proxy bean by removing bean interfaces and it should work.

I'm struggling with the same now, and I can't remove interfaces. I figured out different solution for this. On the interface I can mark my parameters by some custom annot:

interface MyInterface {
  void myMetod(@ParamName("foo") Object foo, @ParamName("bar") Object bar);
}

Now in AOP proxy I can get this information in:

MethodSignature.getMethod().getParameterAnnotations()