切入点表达式
- execution:一般用于
指定方法
的执行,用的最多。 - within:指定某些类型的
全部方法
执行,也可用来指定一个包。 - this:Spring Aop是基于动态代理的,生成的bean也是一个代理对象,this就是这个代理对象,当这个对象可以转换为指定的类型时,对应的切入点就是它了,Spring Aop将生效。
- target:当被代理的对象可以转换为指定的类型时,对应的切入点就是它了,Spring Aop将生效。
- args:当执行的方法的参数是
指定类型时生效
。 - @target:当代理的
目标对象
上拥有指定的注解
时生效- 必须是目标对象的类上有指定的注解。
- @args:当执行的方法
参数类型
上拥有指定的注解
时生效。 - @within:只需要
目标对象
的类或者父类上有指定的注解时生效 - @annotation:当执行的
方法
上拥有指定的注解
时生效。 - reference pointcut:(
经常使用
)表示引用其他命名切入点
,@ApectJ风格支持 - bean:当调用的方法是
指定的bean的方法
时生效。
execution -> 一般用于
指定方法
的执行,用的最多
//表示匹配所有方法
execution(* *(..))
//表示匹配rod.spring.Aop中所有的公有方法
execution(public * rod.spring.Aop.*(..))
//表示匹配rod.spring.Aop包及其子包下的所有方法
execution(* rod.spring.Aop..*.*(..))
// 签名:消息发送切面
@Pointcut("execution(* rod.spring.aop.*(..))")
private void logAop(){}
// 签名:消息接收切面
@Pointcut("execution(* rod.spring.aop2.*(..))")
private void logAop2(){}
// 只有满足logAop或者logAop2这个切面都会切进去,&&、||、! 都可以使用
@Pointcut("logAop() || logAop2()")
private void logMessage(){}
within -> 指定某些类型的
全部方法
执行,也可用来指定一个包
// AopController下面所有外部调用方法,都会拦截。
//备注:只能是AopController的方法,子类不会拦截的,此处只能写实现类,接口无效
@Pointcut("within(rod.spring.aop.AopController)")
public void pointCut() {
}
//匹配包以及子包内的所有类
@Pointcut("within(rod.spring.aop..*)")
public void pointCut() {
}
this -> Spring Aop是基于代理的,this就表示代理对象。
// 这样子,就可以拦截到AopController(可以是接口)所有的子类的所有外部调用方法
@Pointcut("this(rod.spring.aop.AopController*)")
public void pointCut() {
}
target -> Spring Aop是基于代理的,target则表示被代理的目标对象。
//只能是实现类
@Pointcut("target(rod.spring.aop.AopController)")
public void pointCut() {
}
args -> args用来匹配方法参数的。
//args() -> 无参
//args(java.lang.String) -> 匹配任何只带一个String参数
//args(…) -> 带任意参数的方法
//args(java.lang.String,…) -> 匹配带任意个参数,但是第一个参数的类型是String的方法。
//args(…,java.lang.String) -> 匹配带任意个参数,但是最后一个参数的类型是String的方法。
//这个匹配的范围非常广,所以一般和别的表达式结合起来使用
@Pointcut("args()")
public void pointCut() {
}
@target -> 匹配当被代理的目标对象对应的类型及其父类型上拥有指定的注解时。
//类上(非方法上)Test注解的所有外部调用方法
@Pointcut("@target(rod.spring.aop.Test)")
public void pointCut() {
}
@args -> 匹配被调用的方法上含有参数,且对应的参数类型上拥有指定的注解的情况。
// 匹配方法(非类)参数类型上拥Test注解的方法调用。
//如我们有一个方法add(MyParam param)接收一个MyParam类型的参数
//而MyParam这个类是拥有注解Test的,则它可以被Pointcut表达式匹配上
@Pointcut("@args(rod.spring.aop.Test)")
public void pointCut() {
}
@annotation -> 用于匹配方法上拥有指定注解的情况(使用得非常多)。
// 可以匹配所有方法上标有此注解的方法
@Pointcut("@annotation(rod.spring.aop.Test)")
public void pointCut() {
}
reference pointcut -> 切入点引用(使用得非常多)
@Pointcut("execution(* rod.spring.aop.*.*(..)) ")
public void point() {
}
// 这个就是一个`reference pointcut`
// 甚至还可以这样 @Before("point1() && point2()")
@Before("point()")
public void before() {
System.out.println("this is from HelloAspect#before...");
}
bean -> 这是Spring增加的一种方法,spring独有
// 这个就能切入到AopController类的素有的外部调用的方法里
@Pointcut("bean(AopController)")
public void pointCut() {
}
类型匹配语法
*
:匹配任何数量字符;…
:匹配任何数量字符的重复,如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数。+
:匹配指定类型的子类型;仅能作为后缀放在类型模式后边。
表达式的组合
bean(userService) && args()
- 匹配id或name为userService的bean的所有无参方法。
bean(userService) || @annotation(MyAnnotation)
- 匹配id或name为userService的bean的方法调用,或者是方法上使用了MyAnnotation注解的方法调用。
bean(userService) && !args()
- 匹配id或name为userService的bean的所有有参方法调用。