表达式 | 描述 |
execution | 匹配方法执行的连接点,也就是哪些方法要应用切面 |
within | 用来限定连接点必须在确定的类型或包中 |
this | 用来限定连接点属于给定类型的一个实例(代理对象) |
target | 用来限定连接点属于给定类型的一个实例(被代理对象) |
args | 用来限定连接点,也就是方法执行时它的参数属于给定类型的一个实例 |
bean | 用来指定某个bean执行切面方法 |
@annotation | 用来限定连接点的方法拥有给定注解 |
@target | 用来限定连接点属于一个执行对象(被代理对象)所属的拥有给定注解的类 |
@args | 用来限定连接点,方法执行时传递的参数的运行时类型拥有给定注解 |
@within | 用来限定连接点属于拥有给定注解的类型中 |
execution
访问修饰符 返回值 包名.包名.包名 ..类名.方法名(参数列表)
public void com.du.service.impl .AccountServiceImpl.saveAccount()
* *.*.*.*.AccountServiceImpl.saveAccount(..)
访问修饰符 可以省略
返回值 任意返回值 *
包 有几级包,就需要写几个*. * *.*.*.*.AccountServiceImpl.saveAccount())
..表示当前包及其子包 * *..AccountServiceImpl.saveAccount(
方法名都可以使用* 来实现通配
参数 (..)
within
限定连接点必须在确定的类型或包中
@Before("within(com.du.controller.goodController)")
@Pointcut("within(com.du.controller.mallController)")
within()所指定的连接点最小范围只能是类,而execution()所指定的连接点可以大到包,小到方法入参。 所以从某种意义上讲,execution()函数功能涵盖了within()函数的功能
@within
限定连接点属于拥有给定注解的类型中
所执行的方法必须属于拥有给定注解的类型中
@Before("within(com.du.server.Fruit.*) && @within(org.springframework.validation.annotation.Validated)")
this
限定连接点属于给定类型的一个实例(代理对象)
不管方法是来源于哪个接口或类,只要代理对象的实例属于this中所定义的类型,那么这个方法就会被拦截。
@Before("this(com.du.controller.OpcController)")
target
限定连接点属于给定类型的一个实例(被代理对象)
this中的实例指的是代理对象
target中的实例指的是被代理对象。
@Before("target(com.du.controller.OpcController)")
@target
限定连接点属于一个执行对象(被代理对象)所属的拥有给定注解的类。
虽然@target和target名称相似,但是它们用法是完全不同的,前者针对注解,后置针对类型。
@Before("within(com.du.server.Fruit.*) && @target(org.springframework.validation.annotation.Validated)")
@target限定在一个执行对象的所属类,与它的父类接口无关,即@target指定的注解只能放在需要被增强的方法所属的类中,若该类实现了某接口,将注解放在该接口上是不生效的。
args
@Before("within(com.du.controller.OpcController.*) && args(java.lang.Integer, java.lang.String)")
@args
限定连接点,方法执行时传递的参数的运行时类型拥有给定注解。这个给定的注解要么定义在方法参数的类型本身上,那么定义在的它的实现类上。
@Before("within(com.du.server.Fruit.*) && @args(com.fasterxml.jackson.databind.annotation.JsonDeserialize)")
bean
对某个类进行拦截,也就是通过execution指定某个方法时,可能指定的这个方法是接口里的,这个接口又被很多个类实现,此时就可以使用bean对指定的类进行拦截。
@Before("execution(com.du.server.Fruit(..)) && bean(Apple)")
上方的例子中,Fruit是一个接口,里面有一个方法为Apple、Banana分别实现了这个接口,例子中bean指定了Apple这个类,则在拦截时,只会拦截Apple这个类的buy方法。
@annotation
@GetMapping、@PostMapping、@DeleteMapping
@Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping)"