在项目中需要利用Spring AOP对所有的controller方法进行拦截,很容易想到利用切入点表达式中的@annotation对RequestMapping注解进行切面编程。例如:
@Around("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
public Object actionAround(ProceedingJoinPoint pjp) throws Throwable {
Object result = pjp.proceed();
System.out.println("actionAround");
return result;
}
然而这种情况下,如果controller上是GetMapping,则不会生效,例如下面这种
@RestController
public class FooController {
@GetMapping("foo")
public String foo() {
return "foo";
}
}
因此要把GetMapping,PutMapping,PostMapping这些都写上去,切面表达式修改成了
@Around("@annotation(org.springframework.web.bind.annotation.RequestMapping)"
+ "|| @annotation(org.springframework.web.bind.annotation.GetMapping)"
+ "|| @annotation(org.springframework.web.bind.annotation.PostMapping)"
+ "|| @annotation(org.springframework.web.bind.annotation.DeleteMapping)"
+ "|| @annotation(org.springframework.web.bind.annotation.PutMapping)"
+ "|| @annotation(org.springframework.web.bind.annotation.PatchMapping)"
)
public Object actionAround(ProceedingJoinPoint pjp) throws Throwable {
Object result = pjp.proceed();
System.out.println("actionAround");
return result;
}
这样到时达到要求了,但是感觉代码行数太多,有没有什么巧妙的方法呢?
一开始想到了利用通配符,匹配org.springframework.web.bind.annotation
包里所有以Mapping
结尾的注解,改成
@Around("@annotation(org.springframework.web.bind.annotation.*Mapping)")
public Object actionAround(ProceedingJoinPoint pjp) throws Throwable {
Object result = pjp.proceed();
System.out.println("actionAround");
return result;
}
然而@annotation并不支持通配符,看一下@annotation的定义:
AtAnnotation := ‘@annotation’ ‘(’ AnnotationOrIdentifier ‘)’
就是说@annotation后面括号里是AnnotationOrIdentifier,那么AnnotationOrIdentifier定义又是什么呢?
AnnotationOrIdentifier := FullyQualifiedName | Identifier
看样子不像能写通配符的样子。
仔细看了一下,GetMapping,PostMapping这些注解实际上就是带有RequestMapping的注解
例如GetMapping就带有了RequestMapping,并且设置了method
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.GET)
public @interface GetMapping
所以切面表达式应该是满足一下两种条件:
- 带有RequestMapping注解的方法
- 带有带有RequestMapping注解的注解的方法
@Around("execution(@(@org.springframework.web.bind.annotation.RequestMapping *) * *(..))" +
"|| @annotation(org.springframework.web.bind.annotation.RequestMapping)")
public Object actionAround(ProceedingJoinPoint pjp) throws Throwable {
Object result = pjp.proceed();
System.out.println("actionAround");
return result;
}
另外由于带有RequestMapping的注解也都在·org.springframework.web.bind.annotation·包中,并且以Mapping结尾,因此可以使用如下表达式一网打尽:
@Around("execution(@(org.springframework.web.bind.annotation.*Mapping) * *(..))")
public Object actionAround(ProceedingJoinPoint pjp) throws Throwable {
Object result = pjp.proceed();
System.out.println("actionAround");
return result;
}
热门评论
有用到?