切入点决定额外功能加入位置(方法)
<!--execution(* * (..)) 匹配了所有方法-->
<aop:pointcut id="pc" expression="execution(* * (..))"/>
execution()
:切入点函数
* *(..)
:切入点表达式
一、切入点表达式
1.1 方法切入点
//定义一个方法
public void add(int i, int j)
* * (..)
简单说明:
* * (..)
:所有方法
第一个*
:修饰符 返回值
第二个*
:方法名
()
:参数表
..
:—> 对于参数没有要求 (参数有没有,参数有⼏个都行,参数是什么类型的都行)
- 定义
login
方法作为切入点:
<!-- 定义login作为切入点 -->
<aop:pointcut id="pc" expression="execution(* login (..))"/>
<!-- 定义register作为切入点 -->
<aop:pointcut id="pc" expression="execution(* register (..))"/>
- 定义方法名为 login 且 有两个字符串类型的参数 作为切入点;
<aop:pointcut id="pc" expression="execution(* login (String,String))"/><
<!-- ⾮ java.lang java.lang 包中的类型, 必须要写全限定名 -->
<aop:pointcut id="pc" expression="execution(* register (com.yusael.proxy.User))"/>
<!-- ..可以和具体的参数类型连用 -->
<aop:pointcut id="pc" expression="execution(* login(String, ..))"/>
<!-- === login(String), login(String,String), login(String,com.baizhi.edu.proxy.User) -->
- 精准方法切入点限定
修饰符 返回值 包 类.方法 (参数)
<aop:pointcut id="pc" expression="execution(* com.zqc.proxy.UserServiceImpl.login(..))"/>
<aop:pointcut id="pc" expression="execution(* com.zqc.proxy.UserServiceImpl.login(String, String))"/>
1.2 类切入点
指定特定类作为切入点(额外功能加入的位置),这个类中的所有方法,都会加上对应的额外功能。
- 方法1
类中所有的方法加入了额外功能
<aop:pointcut id="pc" expression="execution(* com.zqc.proxy.UserServiceImpl.*(..))"/>
- 方法2
1. 类只存在一级包
<aop:pointcut id="pc" expression="execution(* *.UserServiceImpl.*(..))"/>
2. 类存在多级包
<aop:pointcut id="pc" expression="execution(* *..UserServiceImpl.*(..))"/>
1.3 包切入点(实战中用的多)
指定包作为额外功能加入的位置,自然包中的所有类及其方法都会加入额外的功能。
- 方法1
切入点包中的所有类,必须在proxy中,不能在proxy包的⼦包中
<aop:pointcut id="pc" expression="execution(* com.zqc.proxy.*.*(..))"/>
- 方法2
切入点当前包及其⼦包都生效
<aop:pointcut id="pc" expression="execution(* com.zqc.proxy..*.*(..))"/>
二、切入点函数
切入点函数:用于执行切入点表达式
2.1 exectuion
execution
是最为重要的切入点函数,功能最全;可以执行执行 方法切入点表达式、类切入点表达式、包切入点表达式;
弊端:execution
执⾏切入点表达式 ,书写麻烦
execution(* com.zqc.proxy..*.*(..))
注意:其他的切入点函数
简化的是 execution 的书写复杂度,功能上完全⼀致。
2.2 args
args
作用:主要用于函数(方法) 参数的匹配;
切入点:方法参数必须得是 2 个字符串类型的参数
# 使用 execution
<aop:pointcut id="pc" expression="execution(* *(String, String))"/>
# 使用 args
<aop:pointcut id="pc" expression="args(String, String)"/>
2.3 within
within
作用:主要用于进行 类、包切入点表达式 的匹配。
切入点: UserServiceImpl 这个类
# 使用 execution
<aop:pointcut id="pc" expression="expression(* *..UserServiceImpl.*(..))"/>
# 使用 within
<aop:pointcut id="pc" expression="within(*..UserServiceImpl)"/>
切入点: com.zqc.proxy 这个包
# 使用 execution
<aop:pointcut id="pc" expression="execution(* com.zqc.proxy..*.**(..)"/>
# 使用 within
<aop:pointcut id="pc" expression="within(com.zqc.proxy..*)"/>
2.4 @annotation
作用:为具有特殊注解的方法
加入额外功能。
例如我们自定义了一个注解:Log
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
}
然后我们要为使用了 Log
注解的方法加入额外功能。
<aop:pointcut id="pc" expression="@annotation(com.zqc.Log)"/>
2.5 切入点函数的逻辑运算(and、or)
切入点函数的逻辑运算 指的是:整合多个切入点函数⼀起配合工作,进而完成更为复杂的需求。
and 与操作
案例: 方法名叫 login 同时 参数是 2个字符串
# execution
<aop:pointcut id="pc" expression="execution(* login(String, String))"/>
# execution and args
<aop:pointcut id="pc" expression="execution(* login(..)) and args(String, String))"/>
注意:与操作不同⽤于同种类型的切⼊点函数
以下这个是错误的, 因为不存在同时叫 login 和 register 的方法
<aop:pointcut id="pc" expression="execution(* login(..)) and execution(* register(..))"/>
or 或操作
案例: 方法名叫 register 或 login 的⽅法作为切⼊点
<aop:pointcut id="pc" expression="execution(* login(..)) or execution(* register(..))"/>