Java AOP JoinPoint does not get parameter names

梦想的初衷 提交于 2020-01-01 06:18:44

问题



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.


回答1:


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()



回答2:


I could make this work in Eclipse with Java 8 only . Here's how:

  • Right Click on the project -> Properties -> Java Build Path -> Libraries tab and make sure you add there a JDK 8 instead of what you have now (in my case I had JDK_1.7.0_51 and replaced it with JDK_1.8.0_05). Apply changes.
  • Go to Java Compiler -> Check Enable project specific settings -> Check Use default compliance settings and set Compiler compliance level to 1.8. The same goes for Generated .class files compatibility and Source compatibility.
  • At the Classfile Generation section make sure to check Store method parameter names option (in my tests, I had all the options under Classfile Generation checked). The Store method parameter names option was available in my case only for a compliance level of 1.8. Click Ok.
  • Clean and re-compile your project.
  • I have, also, run my project on Tomcat 7 with JDK 8. No need to run it in Debug mode.

Tested this in STS 3.5.1 (Eclipse Kepler SR2 4.3.2).




回答3:


The simplest way is to set proxyTargetClass in your config file, i.e.

@EnableAspectJAutoProxy(proxyTargetClass = true)


来源:https://stackoverflow.com/questions/25226441/java-aop-joinpoint-does-not-get-parameter-names

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!