Spring-AOP-基于注解的AOP通知执行顺序

本文内容纲要:

- Spring-AOP-基于注解的AOP通知执行顺序

- Spring版本不一样,通知执行顺序可能也会存在差异

- 一、单个切面类

- (1)@Before、@After、@AfterReturning、@AfterThrowing执行顺序

-   ①Spring4.0

-   正常情况:@Before=====目标方法=====@After=====@AfterReturning

-    异常情况:@Before=====目标方法=====@After=====@AfterThrowing

-   正常情况:@Before=====目标方法=====@AfterReturning=====@After

-    异常情况:@Before=====目标方法=====@AfterThrowing=====@After

- (2)@Around的执行顺序

-   ①Spring4.0

-     正常情况:环绕前置=====目标方法执行=====环绕返回=====环绕最终

-     异常情况:环绕前置=====目标方法执行=====环绕异常=====环绕最终

-   ②Spring5.28

-     正常情况:环绕前置=====目标方法执行=====环绕返回=====环绕最终

-     异常情况:环绕前置=====目标方法执行=====环绕异常=====环绕最终

- (3)五大通知执行顺序

-   ①Spring4.0

-     正常情况:环绕前置=====@Before======目标方法执行=====环绕返回=====环绕最终=====@After=====@AfterReturning

-     异常情况:环绕前置=====@Before======目标方法执行=====环绕异常=====环绕最终=====@After=====@AfterThrowing

-   ②Spring5.28

-     正常情况:环绕前置=====@Before=====目标方法执行=====@AfterReturning=====@After=====环绕返回=====环绕最终

-     异常情况:环绕前置=====@Before=====目标方法执行=====@AfterThrowing=====@After=====环绕异常=====环绕最终

- 二、多个切面

-   ①Spring4.0

-     正常情况:切面1环绕前置===切面1@Before===切面2环绕前置===切面2@Before===目标方法执行===切面2环绕返回===切面2环绕最终===切面2@After===切面2@AfterReturning===切面1环绕返回===切面1环绕最终===切面1@After===切面1@AfterThrowing

-     异常情况:切面1环绕前置===切面1@Before===切面2环绕前置===切面2@Before===目标方法执行===切面2环绕异常===切面2环绕最终===切面2@After===切面2@AfteThrowing===切面1环绕异常===切面1环绕最终===切面1@After===切面1@AfterThrowing

-   ②Spring5.28

-     正常情况:切面1环绕前置===切面1@Before===切面2环绕前置===切面2@Before===目标方法执行===切面2@AfterReturning===切面2@After===切面2环绕返回===切面2环绕最终===切面1@AfterReturning===切面1@After===切面1环绕返回===切面1环绕最终

-     异常情况:切面1环绕前置===切面1@Before===切面2环绕前置===切面2@Before===目标方法执行===切面2@AfterThrowing===切面2@After===切面2环绕异常===切面2环绕最终===切面1@AfterThrowing===切面1@After===切面1环绕异常===切面1环绕最终

- 三、可以使用@Order注解指定先后顺序,数字越小,优先级越高,先进后出

Spring-AOP-基于注解的AOP通知执行顺序

通知的选取规则

五大通知类型中,环绕通知功能最为强大,因为环绕通知,可以控制目标方法是否执行。

如果需要记录异常信息,使用异常通知。

其他通知,只能做记录工作,不能做处理,所以执行顺序其实对整个程序影响不大,没有必要太深究。

Spring版本不一样,通知执行顺序可能也会存在差异

下面以Spring4.0版本、Spring5.28版本进行测试

一、单个切面类

(1)@Before、@After、@AfterReturning、@AfterThrowing执行顺序

  ①Spring4.0

  正常情况:@Before=====目标方法=====@After=====@AfterReturning

 **  异常情况:@Before=====目标方法=====@After=====@AfterThrowing**

**  ②Spring5.28**

  正常情况:@Before=====目标方法=====@AfterReturning=====@After

 **  异常情况:@Before=====目标方法=====@AfterThrowing=====@After**

ImageImage

@Service

public class BookService {

public int add(int i,int j)

{

int result=i+j;

System.out.println("目标方法执行");

//System.out.println(1/0);

return result;

}

}

@Aspect

@Component

public class BookServiceProxy {

@Pointcut(value = "execution(* com.orz.spring.aop.BookService.add(..))")

public void myPointCut(){}

@Before(value = "myPointCut()")

public void before()

{

System.out.println("@Before");

}

@After(value = "myPointCut()")

public void after()

{

System.out.println("@After");

}

@AfterReturning(value = "myPointCut()")

public void afterReturning()

{

System.out.println("@AfterReturning");

}

@AfterThrowing(value = "myPointCut()")

public void afterThrowing()

{

System.out.println("@AfterThrowing");

}

}

@Test

public void test2()

{

ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean2.xml");

BookService bookService = applicationContext.getBean("bookService", BookService.class);

bookService.add(1,2);

}

Spring4.0

正常情况

@Before

目标方法执行

@After

@AfterReturning

异常情况

@Before

目标方法执行

@After

@AfterThrowing

Spring5.28

正常情况

@Before

目标方法执行

@AfterReturning

@After

异常情况

@Before

目标方法执行

@AfterThrowing

@After

View Code

(2)@Around的执行顺序

@Around(value = "myPointCut()")

public Object myAround(ProceedingJoinPoint proceedingJoinPoint)

{

Object[] args = proceedingJoinPoint.getArgs();

Object result=null;

try {

//前置通知@Before

System.out.println("环绕前置通知");

//目标方法执行

result = proceedingJoinPoint.proceed(args);

//环绕返回通知@AfterReturning

System.out.println("环绕返回通知");

} catch (Throwable throwable) {

//环绕异常通知@AfterThrowing

System.out.println("环绕异常通知");

throw new RuntimeException(throwable);

} finally {

//最终通知@After

System.out.println("环绕最终通知");

}

return result;

}

  ①Spring4.0

    正常情况:环绕前置=====目标方法执行=====环绕返回=====环绕最终

    异常情况:环绕前置=====目标方法执行=====环绕异常=====环绕最终

  ②Spring5.28

    正常情况:环绕前置=====目标方法执行=====环绕返回=====环绕最终

    异常情况:环绕前置=====目标方法执行=====环绕异常=====环绕最终

ImageImage

@Service

public class BookService {

public int add(int i,int j)

{

int result=i+j;

System.out.println("目标方法执行");

return result;

}

}

@Aspect

@Component

public class BookServiceProxy {

@Pointcut(value = "execution(* com.orz.spring.aop.BookService.add(..))")

public void myPointCut(){}

@Around(value = "myPointCut()")

public Object myAround(ProceedingJoinPoint proceedingJoinPoint)

{

Object[] args = proceedingJoinPoint.getArgs();

Object result=null;

try {

//前置通知@Before

System.out.println("环绕前置通知");

//目标方法执行

result = proceedingJoinPoint.proceed(args);

//环绕返回通知@AfterReturning

System.out.println("环绕返回通知");

} catch (Throwable throwable) {

//环绕异常通知@AfterThrowing

System.out.println("环绕异常通知");

throw new RuntimeException(throwable);

} finally {

//最终通知@After

System.out.println("环绕最终通知");

}

return result;

}

}

@Test

public void test2()

{

ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean2.xml");

BookService bookService = applicationContext.getBean("bookService", BookService.class);

bookService.add(1,2);

}

Spring4.0

环绕前置通知

目标方法执行

环绕返回通知

环绕最终通知

异常情况

环绕前置通知

目标方法执行

环绕异常通知

环绕最终通知

Spring5.28

正常情况

环绕前置通知

目标方法执行

环绕返回通知

环绕最终通知

异常情况

环绕前置通知

目标方法执行

环绕异常通知

环绕最终通知

View Code

(3)五大通知执行顺序

  ①Spring4.0

    正常情况:环绕前置=====@Before======目标方法执行=====环绕返回=====环绕最终=====@After=====@AfterReturning

    异常情况:环绕前置=====@Before======目标方法执行=====环绕异常=====环绕最终=====@After=====@AfterThrowing

  ②Spring5.28

    正常情况:环绕前置=====@Before=====目标方法执行=====@AfterReturning=====@After=====环绕返回=====环绕最终

    异常情况:环绕前置=====@Before=====目标方法执行=====@AfterThrowing=====@After=====环绕异常=====环绕最终

ImageImage

@Service

public class BookService {

public int add(int i,int j)

{

int result=i+j;

System.out.println("目标方法执行");

//System.out.println(1/0);

return result;

}

}

@Aspect

@Component

public class BookServiceProxy {

@Pointcut(value = "execution(* com.orz.spring.aop.BookService.add(..))")

public void myPointCut(){}

@Before(value = "myPointCut()")

public void before()

{

System.out.println("@Before");

}

@After(value = "myPointCut()")

public void after()

{

System.out.println("@After");

}

@AfterReturning(value = "myPointCut()")

public void afterReturning()

{

System.out.println("@AfterReturning");

}

@AfterThrowing(value = "myPointCut()")

public void afterThrowing()

{

System.out.println("@AfterThrowing");

}

@Around(value = "myPointCut()")

public Object myAround(ProceedingJoinPoint proceedingJoinPoint)

{

Object[] args = proceedingJoinPoint.getArgs();

Object result=null;

try {

//前置通知@Before

System.out.println("环绕前置通知");

//目标方法执行

result = proceedingJoinPoint.proceed(args);

//环绕返回通知@AfterReturning

System.out.println("环绕返回通知");

} catch (Throwable throwable) {

//环绕异常通知@AfterThrowing

System.out.println("环绕异常通知");

throw new RuntimeException(throwable);

} finally {

//最终通知@After

System.out.println("环绕最终通知");

}

return result;

}

}

@Test

public void test2()

{

ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean2.xml");

BookService bookService = applicationContext.getBean("bookService", BookService.class);

bookService.add(1,2);

}

Spring4.0

正常情况

环绕前置通知

@Before

目标方法执行

环绕返回通知

环绕最终通知

@After

@AfterReturning

异常情况

环绕前置通知

@Before

目标方法执行

环绕异常通知

环绕最终通知

@After

@AfterThrowing

Spring5.28

正常情况

环绕前置通知

@Before

目标方法执行

@AfterReturning

@After

环绕返回通知

环绕最终通知

异常情况

环绕前置通知

@Before

目标方法执行

@AfterThrowing

@After

环绕异常通知

环绕最终通知

View Code

二、多个切面

Image

  ①Spring4.0

    正常情况:切面1环绕前置===切面1@Before===切面2环绕前置===切面2@Before===目标方法执行===切面2环绕返回===切面2环绕最终===切面2@After===切面2@AfterReturning===切面1环绕返回===切面1环绕最终===切面1@After===切面1@AfterThrowing

    异常情况:切面1环绕前置===切面1@Before===切面2环绕前置===切面2@Before===目标方法执行===切面2环绕异常===切面2环绕最终===切面2@After===切面2@AfteThrowing===切面1环绕异常===切面1环绕最终===切面1@After===切面1@AfterThrowing

  ②Spring5.28

    正常情况:切面1环绕前置===切面1@Before===切面2环绕前置===切面2@Before===目标方法执行===切面2@AfterReturning===切面2@After===切面2环绕返回===切面2环绕最终===切面1@AfterReturning===切面1@After===切面1环绕返回===切面1环绕最终

    异常情况:切面1环绕前置===切面1@Before===切面2环绕前置===切面2@Before===目标方法执行===切面2@AfterThrowing===切面2@After===切面2环绕异常===切面2环绕最终===切面1@AfterThrowing===切面1@After===切面1环绕异常===切面1环绕最终

ImageImage

@Service

public class BookService {

public int add(int i,int j)

{

int result=i+j;

System.out.println("目标方法执行");

//System.out.println(1/0);

return result;

}

}

@Aspect

@Component

public class BookServiceProxy {

@Pointcut(value = "execution(* com.orz.spring.aop.BookService.add(..))")

public void myPointCut(){}

@Before(value = "myPointCut()")

public void before()

{

System.out.println("切面一:@Before");

}

@After(value = "myPointCut()")

public void after()

{

System.out.println("切面一:@After");

}

@AfterReturning(value = "myPointCut()")

public void afterReturning()

{

System.out.println("切面一:@AfterReturning");

}

@AfterThrowing(value = "myPointCut()")

public void afterThrowing()

{

System.out.println("切面一:@AfterThrowing");

}

@Around(value = "myPointCut()")

public Object myAround(ProceedingJoinPoint proceedingJoinPoint)

{

Object[] args = proceedingJoinPoint.getArgs();

Object result=null;

try {

//前置通知@Before

System.out.println("切面一:环绕前置通知");

//目标方法执行

result = proceedingJoinPoint.proceed(args);

//环绕返回通知@AfterReturning

System.out.println("切面一:环绕返回通知");

} catch (Throwable throwable) {

//环绕异常通知@AfterThrowing

System.out.println("切面一:环绕异常通知");

throw new RuntimeException(throwable);

} finally {

//最终通知@After

System.out.println("切面一:环绕最终通知");

}

return result;

}

}

@Test

public void test2()

{

ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean2.xml");

BookService bookService = applicationContext.getBean("bookService", BookService.class);

bookService.add(1,2);

}

Spring4.0

正常情况

切面一:环绕前置通知

切面一:@Before

切面二:环绕前置通知

切面二:@Before

目标方法执行

切面二:环绕返回通知

切面二:环绕最终通知

切面二:@After

切面二:@AfterReturning

切面一:环绕返回通知

切面一:环绕最终通知

切面一:@After

切面一:@AfterReturning

异常情况

切面一:环绕前置通知

切面一:@Before

切面二:环绕前置通知

切面二:@Before

目标方法执行

切面二:环绕异常通知

切面二:环绕最终通知

切面二:@After

切面二:@AfterThrowing

切面一:环绕异常通知

切面一:环绕最终通知

切面一:@After

切面一:@AfterThrowing

Spring5.28

正常情况

切面一:环绕前置通知

切面一:@Before

切面二:环绕前置通知

切面二:@Before

目标方法执行

切面二:@AfterReturning

切面二:@After

切面二:环绕返回通知

切面二:环绕最终通知

切面一:@AfterReturning

切面一:@After

切面一:环绕返回通知

切面一:环绕最终通知

异常情况

切面一:环绕前置通知

切面一:@Before

切面二:环绕前置通知

切面二:@Before

目标方法执行

切面二:@AfterThrowing

切面二:@After

切面二:环绕异常通知

切面二:环绕最终通知

切面一:@AfterThrowing

切面一:@After

切面一:环绕异常通知

切面一:环绕最终通知

View Code

三、可以使用@Order注解指定先后顺序,数字越小,优先级越高,先进后出

可以使用@Order注解指定先后顺序,数字越小,优先级越高,先进后出

@Order(value = 1)

@Aspect

@Component

public class BookServiceProxy {}

@Order(value = 0)

@Aspect

@Component

public class BookServiceProxy2 {}

切面二:环绕前置通知

切面二:@Before

切面一:环绕前置通知

切面一:@Before

目标方法执行

切面一:@AfterReturning

切面一:@After

切面一:环绕返回通知

切面一:环绕最终通知

切面二:@AfterReturning

切面二:@After

切面二:环绕返回通知

切面二:环绕最终通知

  

本文内容总结:Spring-AOP-基于注解的AOP通知执行顺序,Spring版本不一样,通知执行顺序可能也会存在差异,一、单个切面类,(1)@Before、@After、@AfterReturning、@AfterThrowing执行顺序,  ①Spring4.0,  正常情况:@Before=====目标方法=====@After=====@AfterReturning,   异常情况:@Before=====目标方法=====@After=====@AfterThrowing,  正常情况:@Before=====目标方法=====@AfterReturning=====@After,   异常情况:@Before=====目标方法=====@AfterThrowing=====@After,(2)@Around的执行顺序,  ①Spring4.0,    正常情况:环绕前置=====目标方法执行=====环绕返回=====环绕最终,    异常情况:环绕前置=====目标方法执行=====环绕异常=====环绕最终,  ②Spring5.28,    正常情况:环绕前置=====目标方法执行=====环绕返回=====环绕最终,    异常情况:环绕前置=====目标方法执行=====环绕异常=====环绕最终,(3)五大通知执行顺序,  ①Spring4.0,    正常情况:环绕前置=====@Before======目标方法执行=====环绕返回=====环绕最终=====@After=====@AfterReturning,    异常情况:环绕前置=====@Before======目标方法执行=====环绕异常=====环绕最终=====@After=====@AfterThrowing,  ②Spring5.28,    正常情况:环绕前置=====@Before=====目标方法执行=====@AfterReturning=====@After=====环绕返回=====环绕最终,    异常情况:环绕前置=====@Before=====目标方法执行=====@AfterThrowing=====@After=====环绕异常=====环绕最终,二、多个切面,  ①Spring4.0,    正常情况:切面1环绕前置===切面1@Before===切面2环绕前置===切面2@Before===目标方法执行===切面2环绕返回===切面2环绕最终===切面2@After===切面2@AfterReturning===切面1环绕返回===切面1环绕最终===切面1@After===切面1@AfterThrowing,    异常情况:切面1环绕前置===切面1@Before===切面2环绕前置===切面2@Before===目标方法执行===切面2环绕异常===切面2环绕最终===切面2@After===切面2@AfteThrowing===切面1环绕异常===切面1环绕最终===切面1@After===切面1@AfterThrowing,  ②Spring5.28,    正常情况:切面1环绕前置===切面1@Before===切面2环绕前置===切面2@Before===目标方法执行===切面2@AfterReturning===切面2@After===切面2环绕返回===切面2环绕最终===切面1@AfterReturning===切面1@After===切面1环绕返回===切面1环绕最终,    异常情况:切面1环绕前置===切面1@Before===切面2环绕前置===切面2@Before===目标方法执行===切面2@AfterThrowing===切面2@After===切面2环绕异常===切面2环绕最终===切面1@AfterThrowing===切面1@After===切面1环绕异常===切面1环绕最终,三、可以使用@Order注解指定先后顺序,数字越小,优先级越高,先进后出,

原文链接:https://www.cnblogs.com/orzjiangxiaoyu/p/13869747.html

以上是 Spring-AOP-基于注解的AOP通知执行顺序 的全部内容, 来源链接: utcz.com/z/296884.html

回到顶部