一、定义切入点:
在@AspectJ风格的AOP中,切入点签名采用一个普通的方法定义(方法体通常为空)来提供(方法名即为切点名),且该方法的返回值必须为void,切入点表达式需使用@Pointcut注解来标注。如下:
//配置切入点,该方法无方法体,主要为方便同类中其他方法使用此处配置的切入点
@Pointcut("execution(public * com.learn.spring..*.*(..))")
private void pointcut() {
}
一旦采用上面的代码片段定义了名为pointcut的切入点之后,程序就可以多次重复使用该切点了,甚至可以在其他切面类、其他包的切面类里使用该切点,至于是否可以在其他切面类、其他包下使用这个切点,那就要看该方法前的访问控制修饰符了——本例中pointcut使用private修饰,则意味着仅能在当前切面类中使用这个切点。
指定切入点的语法类似于Java中调用方法。假设在另一个类中调用上述代码段定义的切入点poingcut(),调用方式如下:
//引用时带上类名
@After("LearnAspect.pointcut()")
public void after()
{
System.out.println("调用LearnAspect的切入点pointcut()");
}
二、切入点表达式:
切入点表达式,也就是组成@Pointcut注解的值。
类型匹配通配符:
*:匹配任何数量字符;
..:匹配任何数量字符的重复,如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数。
+:匹配指定类型的子类型;仅能作为后缀放在类型模式后边。
示例:
java.lang.String : 匹配String类型
java.*.String : 匹配java包下的任何"一级子包"下的String类型.
java..* : 匹配java包及任何子包下的任何类型
java.lang.*ing : 匹配任何java.lang包下的以ing结尾的类型
java.lang.Number+ : 匹配java.lang包下的任何Number的自类型。如:java.lang.Interger、java.lang.BigInteger
Spring AOP支持的切入点指示符如下:
execution:用于匹配方法执行的连接点;
语法:其中execution 是用的最多的,其格式为:
execution(modifiers-pattern? ret-type-pattern declaring-typ e-pattern? name-pattern(param-pattern)throws-pattern?)
modifiers-pattern:方法的操作权限
ret-type-pattern:必填,返回值,可以使用“*”进行模式匹配
declaring-type-pattern:方法所在的包
name-pattern:必填,方法名,可以使用“*”进行模式匹配
parm-pattern:必填,参数列表,可以使用“*”、“..”进行模式匹配
throws-pattern:异常
示例:
public * *(..) : 任何公共方法的执行
* com.learn..Learn.*() : com.learn包以及子包下Learn类中的任何无参方法
* com.learn..*.*(..) : com.learn包以及子包下的任何类的任何方法
within:用于匹配指定类型内的方法执行;
语法:只能指定包路径,表示是某个包下或者子包下的所有方法。
示例:
within(com.learn.*) : com.learn包下的所有方法。
within(com.learn..*) : com.learn包以及子包下的所有方法。
this:限制连接点匹配AOP代理的bean引用为指定类型的类
用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配;
语法:表达式必须是类型全限定名,不支持通配符
示例:
this(com.learn.ServiceManager) : 匹配实现了ServiceManager接口的代理对象的所有连接点,在Spring中只是方法执行的连接点
target:限制连接点匹配目标对象为指定的类
用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;
语法:表达式必须是类型全限定名,不支持通配符
示例:
target(com.learn.ServiceManager) : 匹配实现了ServiceManager接口的目标对象的所有连接点,在Spring中只是方法执行的连接点
args:用于匹配当前执行的方法传入的参数为指定类型的执行方法;
示例: args(java.io.Serializable,..) : 任何以一个接受传入参数为java.io.serializable开头,其后可跟任意个任意参数类型的执行方法
@within、@target、@annotation、@args这些语法形式主要是针对注解的。注解类型都必须是全限定类型名
@within:限制连接点匹配指定注解所标注的类型(当使用Spring AOP时,方法定义在由指定的注解所标注的类里);
示例: @within(com.learn.Table) : 任何目标对象持有Table注解的类方法。必须是在目标对象上声明这个注解,在接口上声明的对它不起作用
@target:限制连接点匹配特定的执行对象,这些对象对应的类要具有指定类型的注解;
示例:@target(com.learn.Table) : 任何目标对象持有Table注解的类方法。必须是在目标对象上声明这个注解,在接口上声明的对它不起作用
@args:限制连接点匹配参数由指定注解标注的执行方法;
示例:@args(com.learn.Table) : 任何一个只接受一个参数的方法,且传入参数持有Table注解
@annotation:限定匹配带有指定注解的连接点;
示例:@annotation(com.learn.Table) : 当前执行方法上持有Table注解,将被匹配
bean:Spring AOP扩展的,AspectJ没有对于指示符,用于匹配特定名称的Bean对象的执行方法;
示例:bean(*Service) : 匹配所有以Service命名结尾的Bean
组合切点表达式
Spring支持使用如下三个逻辑运算符来组合切入点表达式:
&&:要求连接点同时匹配两个切点表达式
||:要求连接点匹配至少一个切入点表达式
!:要求连接点不匹配指定的切入点表达式