SpringAOP - 3.通知

Smile_slime_47

通知分类


通知主要分为五类,由各自对应的注解调用:

  • @Before:方法执行前通知
  • @After:方法执行后,返回前通知,抛出异常仍会继续执行
  • @AfterReturning:方法执行后,返回后通知,抛出异常时不会执行
  • @AfterThrowing:抛出异常后通知
  • @Around:环绕通知

这些通知的参数传入对应的切点方法

1
2
3
4
5
6
7
8
9
10
11
@Component
@Aspect
public class aspect{
@Pointcut("execution(* org.example..*.*(..))")
public void pt1(){}

@Before("pt1()")
public void advice1(){
...
}
}

环绕通知@Around

在使用环绕通知时,通知方法的参数必须包含一个ProceedingJoinPoint类,在通知中通过调用该类的proceed()方法来执行切入点方法,否则切入点方法不会被执行

通过环绕通知,我们可以一次性实现多种通知位置,有更高的自由度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Component
@Aspect
public class aspect{
@Pointcut("execution(* org.example..*.*(..))")
public void pt1(){}

@Around("pt1()")
public Object around(ProceedingJoinPoint pjp){
System.out.println("Before");
Object ans=null;
try{
ans=pjp.proceed();
System.out.println("AfterReturning");
}catch(Throwable throwable){
System.out.println("AfterThrowing");
}finally{
System.out.println("After");
}
return ans;
}
}

获取切入点信息


为了在通知方法中获取通知点的信息,我们需要在通知方法的参数列表中添加一个JoinPoint的类

  • 环绕通知中对应ProceedingJoinPoint

在通知方法中调用JoinPoint的方法即可获取到切入点的相关信息

1
2
3
4
5
6
7
8
9
10
11
12
@Component
@Aspect
public class aspect{
@Pointcut("execution(* org.example..*.*(..))")
public void pt1(){}

@Before("pt1()")
public void advice1(JoinPoint jp){
System.out.println(jp.getSignature().getName());
...
}
}

获取返回值和抛出的异常

除在环绕通知中可以通过pjp.proceed()获取方法执行后的返回值和异常外,AfterReturning和AfterThrowing通知也可以通过注解参数获取切入点的返回值和异常

  • 除value参数传入切入点外,还有一个returning参数和throwing参数,用于指明参数列表中的绑定参数
1
2
3
4
5
6
7
8
9
10
11
12
@Component
@Aspect
public class aspect{
@Pointcut("execution(* org.example..*.*(..))")
public void pt1(){}

@AfterReturning(value="pt1()",returning="ret")
public void advice1(JoinPoint jp,Object ret){
System.out.println(jp.getSignature().getName());
...
}
}

则此时advice1中的局部变量ret被绑定为切入点方法的返回值

Comments