[toc]
| 单词 | 词性 | 音标 | 含义 |
|---|---|---|---|
| execution | n. | /ˌeksɪˈkjuːʃn/ | 执行(AOP切点表达式关键字,用于匹配方法执行连接点,可指定方法返回值、类名、方法名及参数) |
| within | prep. | /wɪˈðɪn/ | 在……之内(AOP切点表达式关键字,用于匹配指定类或包中的所有方法执行连接点) |
| args | n. (复数) | /ɑːɡz/ | 参数(AOP切点表达式关键字,用于匹配参数类型符合指定条件的方法执行连接点) |
| annotation | n. | /ˌænəˈteɪʃn/ | 注解(AOP切点表达式关键字,用于匹配被指定注解标注的方法或类的连接点) |
Lecture15-切面-[实验04]切入点表达式语法
1、切入点表达式的作用

2、表达式总体结构
- 如果只有一个核心表达式,那就无需使用逻辑运算符
- 如果核心表达式有多个,那就需要使用逻辑运算符连起来,以便计算出一个最终结果
- 组合表达式中,
&&优先级高于||,建议使用括号明确优先级

3、核心表达式
①总体介绍
| 类型 | 匹配维度 | 示例 | Spring 版本要求 |
|---|---|---|---|
execution | 方法执行 | execution(public * *(..)) | 所有版本(从 Spring 1.0 起) |
within | 类范围 | within(com.example.service.*) | 所有版本 |
args | 参数类型 | args(String, int) | 所有版本 |
@annotation | 方法注解 | @annotation(Transactional) | Spring 2.0+ |
@within | 类注解 | @within(MyService) | Spring 2.0+ |
@target | 目标对象类注解 | @target(MyService) | Spring 2.0+ |
@args | 参数类型注解 | @args(Validated) | Spring 2.0+ |
this | 代理对象接口 | this(MyInterface) | 所有版本 |
target | 目标对象接口 | target(MyInterface) | 所有版本 |
② execution
[1]总述
-
作用:匹配方法执行连接点,是最常用的切入点类型。
-
语法:
execution(权限修饰符? 返回类型 类路径?方法名(参数) throws 异常?) -
示例:
execution(public * com.example.service.*.*(..)) // 匹配Service包下所有public方法
[2]细节:权限修饰符部分

-
权限修饰符可以省略,省略表示所有范围的权限修饰符都可以匹配
- public:当前整个工程都可以访问
- protected:本类、本包和子类
- default:本类和本包
- private:本类(所以切入点表达式省略权限修饰符,有可能锁定私有方法,需要注意)
-
权限修饰符这里要么省略,要么明确指定,不能使用星号!
// 正确写法
// 例1:省略了权限修饰符的部分
execution(int com.atguigu.spring.api.Calculator.mul(int, int))
// 例2:这里的星号是针对方法返回值类型使用通配符,而权限修饰符部分是被省略的
execution(* com.atguigu.spring.api.Calculator.mul(int, int))
// 例3:权限修饰符和方法返回值类型都明确指定
execution(public int com.atguigu.spring.api.Calculator.mul(int, int))
// 错误写法
execution(* int com.atguigu.spring.api.Calculator.mul(int, int))
[3]细节:返回类型部分
- 明确指定返回类型
execution(public int com.atguigu.spring.api.Calculator.mul(int, int))
- 用星号表示任何返回类型都可以
execution(public * com.atguigu.spring.api.Calculator.mul(int, int))
[4]细节:全类名部分
- 可以省略
@Pointcut("execution(public int mul(int, int))")
- 可以明确指定
execution(public int com.atguigu.spring.api.Calculator.mul(int, int))
- 可以使用星号代替整个全类名
execution(public int *.mul(int, int))
- 对于全类名中的包名部分:
// 单独的一个星号,表示这个层级的包名不限
execution(public int *.atguigu.spring.api.Calculator.mul(int, int))
// 星号后面跟两个点,表示包名不限、层次深度不限
execution(public int *..Calculator.mul(int, int))
- 对于全类名中的类名部分:
// 类名完整指定
execution(public int com.atguigu.spring.api.Calculator.mul(int, int))
// 整个类名使用星号
execution(public int com.atguigu.spring.api.*.mul(int, int))
// 类名仅部分指定
// 例如下面表达式表示匹配以Calculator开头的类名
execution(public int com.atguigu.spring.api.Calculator*.mul(int, int))
[5]细节:方法名部分
// 方法名完整指定
execution(public int com.atguigu.spring.api.Calculator.mul(int, int))
// 方法名整个使用星号
execution(public int com.atguigu.spring.api.Calculator.*(int, int))
// 方法名仅部分指定
// 例如下面表达式表示匹配以mul开头的方法名
execution(public int com.atguigu.spring.api.Calculator.mul*(int, int))
[6]细节:参数列表部分
// 完整明确指定参数列表
execution(public int com.atguigu.spring.api.Calculator.mul(int, int))
// 仅部分指定
execution(public int com.atguigu.spring.api.Calculator.mul(int, int, ..))
execution(public int com.atguigu.spring.api.Calculator.mul(int, .., int))
// 参数列表任意
execution(public int com.atguigu.spring.api.Calculator.mul(..))
[7]典型用法举例
execution(* *..*Service.*(..))
③within
- 作用:匹配指定类型内的方法执行。
- 语法:
within(类路径表达式) - 示例:
within(com.example.service.*) // 匹配Service包下所有类的方法 within(com.example.service.UserService+) // 匹配UserService及其子类的方法
④ args
- 作用:匹配参数类型符合指定条件的方法。
- 语法:
args(参数类型列表) - 示例:
args(java.lang.String, int) // 匹配第一个参数为String,第二个为int的方法
⑤@annotation
[1]总述
-
作用:匹配带有指定注解的方法。
-
语法:
@annotation(注解全限定名)全限定名就是全类名
-
示例:
@annotation(org.springframework.transaction.annotation.Transactional) // 匹配带@Transactional的方法
[2]测试:自定义注解

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AtguiguDoSth {
// 声明这个属性是为了将来注解标记在不同方法上,可以设置不同的值
String info() default "happy";
}
[3]测试:把注解标记于目标方法

@Override
@AtguiguDoSth(info = "timi")
public int sub(int i, int j) {
int result = i - j;
System.out.println("方法内部 result = " + result);
return result;
}
[4]测试:切入点表达式

@Component
public class MyPointCut {
@Pointcut("@annotation(com.atguigu.spring.annotation.AtguiguDoSth)")
public void fixPointCut(){}
}
[5]测试:在通知方法读取注解

// 1、获取 MethodSignature 对象
MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
// 2、获取我们标记在目标方法上的注解
AtguiguDoSth annotation = methodSignature.getMethod().getAnnotation(AtguiguDoSth.class);
// 3、读取注解中设置的属性
String info = annotation.info();
⑥@within
- 作用:匹配类上带有指定注解的所有方法。
- 语法:
@within(注解全限定名) - 示例:
@within(com.example.annotation.MyService) // 匹配类上有@MyService注解的所有方法
⑦ @target
- 作用:匹配目标对象类上带有指定注解的方法。
- 语法:
@target(注解全限定名) - 示例:
@target(com.example.annotation.MyService) // 匹配目标对象类有@MyService注解的方法
⑧@args
- 作用:匹配参数类型上带有指定注解的方法。
- 语法:
@args(注解全限定名) - 示例:
@args(com.example.annotation.Validated) // 匹配参数类型带有@Validated注解的方法
⑨this
- 作用:匹配代理对象实现了指定接口的方法。
- 语法:
this(接口类型) - 示例:
this(com.example.service.MyService) // 匹配代理对象实现了MyService接口的方法
⑩target
- 作用:匹配目标对象实现了指定接口的方法。
- 语法:
target(接口类型) - 示例:
target(com.example.service.MyService) // 匹配目标对象实现了MyService接口的方法
⑪ 组合表达式
- 作用:使用逻辑运算符组合多个切入点表达式。
- 运算符:
&&(与)、||(或)、!(非)
- 示例:
execution(* com.example.service.*.*(..)) && !within(com.example.service.impl.*) // 匹配Service包但排除impl子包