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**
@Servicepublic 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
正常情况:环绕前置=====目标方法执行=====环绕返回=====环绕最终
异常情况:环绕前置=====目标方法执行=====环绕异常=====环绕最终
@Servicepublic 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=====环绕异常=====环绕最终
@Servicepublic 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
二、多个切面
①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环绕最终
@Servicepublic 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