通知的选取规则
五大通知类型中,环绕通知功能最为强大,因为环绕通知,可以控制目标方法是否执行。
如果需要记录异常信息,使用异常通知。
其他通知,只能做记录工作,不能做处理,所以执行顺序其实对整个程序影响不大,没有必要太深究。
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
@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
(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
正常情况:环绕前置=====目标方法执行=====环绕返回=====环绕最终
异常情况:环绕前置=====目标方法执行=====环绕异常=====环绕最终
@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
正常情况
环绕前置通知
目标方法执行
环绕返回通知
环绕最终通知
异常情况
环绕前置通知
目标方法执行
环绕异常通知
环绕最终通知
(3)五大通知执行顺序
①Spring4.0
正常情况:环绕前置=====@Before======目标方法执行=====环绕返回=====环绕最终=====@After=====@AfterReturning
异常情况:环绕前置=====@Before======目标方法执行=====环绕异常=====环绕最终=====@After=====@AfterThrowing
②Spring5.28
正常情况:环绕前置=====@Before=====目标方法执行=====@AfterReturning=====@After=====环绕返回=====环绕最终
异常情况:环绕前置=====@Before=====目标方法执行=====@AfterThrowing=====@After=====环绕异常=====环绕最终
@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
环绕异常通知
环绕最终通知
二、多个切面

①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环绕最终
@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
切面一:环绕异常通知
切面一:环绕最终通知
三、可以使用@Order注解指定先后顺序,数字越小,优先级越高,先进后出
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
4272

被折叠的 条评论
为什么被折叠?



