切入点语法
切入点指示符
切入点指示符用来指示切入点表达式目的,Spring AOP目前只支持执行方法这一连接点
指示符 | |
---|---|
execution | 用于匹配方法执行的连接点 |
within | 用于匹配指定类型内的方法执行 |
this | 用于匹配当前AOP代理对象类型的执行方法; 注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配 |
target | 用于匹配当前目标对象类型的执行方法; 注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配 |
args | 用于匹配,当前传入的参数为指定类型的执行方法 |
@target | 用于匹配当前目标对象类型的执行方法。其中目标对象持有指定的注解 |
@within | 用于匹配,所有持有指定注解类型内的方法 |
@args | 用于匹配传入的参数持有指定注解的执行方法 |
@annotation | 用于匹配当前执行方法持有指定注解的方法 |
命名切入点以及匿名切入点
命名切入点可以被其他切入点引用,而匿名切入点不可以
@AspectJ支持命名切入点,Schema风格不支持
@Pointcut(value="execution(public void com.dao.impl.StudentDaoImpl.*Student())")
//命名切入点pointcut()
public void pointcut() {
}
//引用命名切入点pointcut()
@AfterReturning("pointcut()")
public void afterReturning() {
System.out.println("after");
}
//引用命名切入点pointcut()
@Before("pointcut()")
public void before() {
System.out.println("before");
}
类型匹配
-通配符
通配符 | |
---|---|
* | 匹配任何数量字符 |
.. | 匹配任何数量字符的重复 在类模式中匹配任何数量子包 在方法参数模式中匹配任何数量参数 |
+ | 匹配指定类型的子类型;仅能作为后缀放在类型模式后面 |
通配符例子 | |
---|---|
java.lang.String | 匹配String类型 |
java.*.String | 匹配java包下的一级子包的String类型 |
java..* | 匹配java包以及其任何子包下的任何类型,如 java.lang.annotation.Annotation |
java.lang.*ing | 匹配java.lang包下以ing结尾的类型 |
java.lang.Number+ | 匹配java.lang包下任何Number的子类型,如 java.lang.Integer;java.math.BigInteger |
-匹配类型表达式
注解?类的全限定名字
匹配类型 | 是否可选 | |
---|---|---|
注解 | 可选 | 类型上持有的注解 |
类的全限定名 | 必填 |
-匹配方法表达式
注解?修饰符?返回值类型 类型声明?方法名(参数列表) 异常列表?
匹配方法 | 是否可选 | |
---|---|---|
注解 | 可选 | 方法上持有的注解,如@Deprecated |
修饰符 | 可选 | public、protected |
返回值类型 | 必填 | 可以是任何类型;”*”表示所有类型 |
类型声明 | 可选 | |
方法名 | 必填 | 可以用”*”进行模式匹配 |
参数列表 | “()”表示方法没有任何的参数 ”(..)”表示接受任意个参数的方法 ”(..,java.lang.String)”表示匹配接受以String类型的参数结束并且前面可以有任意个参数的方法 ”(*,java.lang.String)”表示匹配接受以String类型的参数结束并且前面可以有任意一个参数的方法 | |
异常列表 | 可选 | “throw 异常全限定名列表”;多个异常则用”,”分隔,如: “throws java.lang.IllegalArgumentException,…,…” |
-组合切入点表达式
AspectJ使用&&、||、!来组合切入点表达式
Schema使用and、or、not
-切入点使用示例
一、execution:使用”execution(方法表达式)”匹配方法执行
模式 | 描述 |
---|---|
public * *(..) | 任何公共方法的执行 |
* com..StudentService.*() | com包以及所有子包下的StudentService的任何无参方法 |
* com..*.*() | com包以及所有子包下任何类的任何无参方法 |
* (!com..StudentService+).*(..) | 非 com包以及所有子包下的 StudentService类以及其子类的任何方法 |
* (com..StudentService+ && java.io.Serializable+).*(..) | |
(@java.lang.Deprecated *) *(..) throws java.lang.IllegalArgumentException |
二、within:使用“within(类型表达式)”匹配指定类型内的方法执行
模式 | 描述 |
---|---|
within(com.fsl..*) | com.fsl包以及子包下的任何类型的任何方法执行 |
within(com.fsl..StudentService+) | com.fsl包以及所有子包下的 StudentService类型以及其子类型的任何方法执行 |
within(@java.lang.Deprecated *) | 持有这个注解的的任何类型的任何方法执行 |
三、this:使用“this(类型的全限定名)”匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口方法也匹配;注意this中使用的表达式必须是类型全限定名,不支持通配符;
模式 | 描述 |
---|---|
this(com.dao.StudentDao) | 当前AOP对象实现了StudentDao接口的任何方法 |
四、target:使用”target(类型全限定名)”匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口方法也匹配;注意target中使用的表达式必须是类型全限定名,不支持通配符;
模式 | 描述 |
---|---|
this(com.dao.StudentDao) | 当前目标对象(非AOP对象)实现了StudentDao接口的任何方法 |
五、args:使用“args(参数类型列表)”匹配当前执行的方法传入的参数属于指定类型的执行方法;注意传入的参数类型,不是匹配方法签名的参数类型;参数类型列表中的参数必须是类型全限定名,通配符不支持;args属于动态切入点,这种切入点开销大,最好不要使用
模式 | 描述 |
---|---|
args(java.io.Serializable,…) | 任何一个以接受传入参数类型为“java.io.Serializable”开头,且后面可以跟任意个类任意类型的参数的方法执行,args执行的参数类型是在运行时动态匹配的 |
还有通知参数和通知顺序没写
附一个简单的例子
http://download.csdn.net/detail/bb10210521/9389382