如何从Spring控制器的AOP建议中获取RequestMapping请求?
问题描述:
由于某种控制器的一个请求映射如何从Spring控制器的AOP建议中获取RequestMapping请求?
@RequestMapping(value="/some/path", method=RequestMethod.POST)
你怎么会在切面类检索方法值(RequestMethod.POST)?
我想跟踪所有执行POST请求的控制器方法。
谢谢
答
找到了解决方案。
import org.aspectj.lang.reflect.MethodSignature;
import java.lang.reflect.Method;
@Pointcut("within(@org.springframework.stereotype.Controller *)")
public void controller() {}
// In advice
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature .getMethod();
RequestMethod[] requestMethods = method.getAnnotation(RequestMapping.class).method();
要小心你导入哪一类。
+0
我仍然认为这不是它应该完成的方式。我自己的答案使用规范的AspectJ,并且不需要反射。 – kriegaex 2015-07-24 09:10:50
答
@ AL13N:您自己的回答是正确的,但是如果您只将注释绑定到参数,则不需要使用反射。这里是POJO + AspectJ中的一个例子。在Spring AOP它应该是相同的,但:
样品控制器主要方法:
package de.scrum_master.app;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class MyController {
@RequestMapping(value="/some/path", method=RequestMethod.POST)
public void foo() {
System.out.println("foo");
}
public void bar() {
System.out.println("bar");
}
public static void main(String[] args) {
MyController controller = new MyController();
controller.foo();
controller.bar();
}
}
看点:
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.web.bind.annotation.RequestMapping;
public aspect RequestMappingInterceptor {
@Pointcut(
"within(@org.springframework.stereotype.Controller *) && " +
"@annotation(requestMapping) && " +
"execution(* *(..))"
)
public void controller(RequestMapping requestMapping) {}
@Before("controller(requestMapping)")
public void advice(JoinPoint thisJoinPoint, RequestMapping requestMapping) {
System.out.println(thisJoinPoint);
System.out.println(" " + requestMapping);
System.out.println(" " + requestMapping.method()[0]);
}
}
BTW,切入点的&& execution(* *(..))
部分在Spring AOP中可能不需要,因为它只是知道执行切入点。在AspectJ中,您需要排除call()
和其他类型的切入点,因为AspectJ更强大。它虽然没有伤害,并且更安全,更明确。
控制台输出:
execution(void de.scrum_master.app.MyController.foo())
@org.springframework.web.bind.annotation.RequestMapping(headers=[], name=, value=[/some/path], produces=[], method=[POST], params=[], consumes=[])
POST
foo
bar
编辑:被交换的参数,从而使连接点的第一通知方法的参数,因为Spring AOP的似乎该订单上坚持而AspectJ的没有。
获取'@ Controller' bean,获取调用的方法,检索注释,获取其'method'属性。 – 2014-11-14 15:45:53