导入坐标:
spring-context已经包含了spring-aop
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>6.1.13</version> </dependency>
aspectjweaver:
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.22.1</version> </dependency>
Spring AOP 的工作原理
Spring AOP使用代理模式来实现AOP。对于Spring中的Bean,默认情况下会使用JDK动态代理,如果目标类没有实现接口,则会使用CGLIB代理。当应用程序调用目标对象的方法时,实际上是调用了代理对象的方法。代理对象负责在适当的时候执行通知,并将调用转发给目标对象。
Spring AOP 的优点
-
提高了代码的重用性和模块化程度。
-
减少了重复代码。
-
提高了系统的可维护性。
切入点表达式语法
execution
是最常用的切入点表达式,用于匹配方法的执行。其语法如下:
execution([modifiers] 返回值类型 包名.类名.方法名(参数列表) [throws 异常类型])
各部分说明
-
modifiers
(可选):-
方法修饰符,例如
public
、private
等。 -
通常可以省略,因为大多数情况下我们不关心修饰符。
-
-
返回值类型
:-
指定方法的返回值类型。
-
使用
*
表示任意返回值类型。 -
示例:
void
、int
、*
。
-
-
包名.类名
:-
指定方法所属的类或包。
-
如果只想匹配某个包下的所有类,可以用通配符
*
。 -
示例:
com.mirror.service.*
。
-
-
方法名
:-
指定具体的方法名称。
-
使用
*
表示任意方法名。
-
-
(参数列表)
:-
指定方法的参数列表。
-
使用
()
表示无参数。 -
使用
(..)
表示任意数量和类型的参数。 -
使用
(java.lang.String, int)
表示精确匹配参数类型。
-
-
throws 异常类型
(可选):-
指定方法可能抛出的异常类型。
-
通常可以省略。
-
示例:
execution(* com.mirror.service.*.*(..)) // 匹配 com.mirror.service 包下所有类的所有方法
参数说明 | 描述 |
---|---|
* | 表示任意返回类型 |
com.mirror.service.* | 匹配指定包下的所有类 |
*.*(..) | 匹配类中所有方法,.. 表示任意参数 |
环绕通知:无返回值时
@Around("pt()") public void around(ProceedingJoinPoint point) throws Throwable { System.out.println("around before"); //表示对原始操作的调用 point.proceed(); System.out.println("around after"); }
环绕通知:有返回值时
@Around("pt()")//这里的返回值必须用object public Object around2(ProceedingJoinPoint point) throws Throwable { System.out.println("around before"); //表示对原始操作的调用 Object proceed = point.proceed(); System.out.println("around after"); //必须抛出返回值,否则报错 return proceed; }