Spring aop 五种通知类型

Spring aop 五种通知类型

spring aop 的五种通知类型

前置通知 Before advice:在连接点前面执行,前置通知不会影响连接点的执行,除非此处抛出异常后置通知 After returning advice:在连接点正常执行完成后执行,如果连接点抛出异常,则不会执行异常通知 After throwing advice:在连接点抛出异常后执行最终通知 After (finally) advice:在连接点执行完成后执行,不管是正常执行完成,还是抛出异常,都会执行返回通知中的内容环绕通知 Around advice:环绕通知围绕在连接点前后,能在方法调用前后自定义一些操作,还需要负责决定是继续处理 join point (调用 ProceedingJoinPoint 的 proceed 方法)还是中断执行

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

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

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

spring aop 通知类型使用

添加 Aspect 切面类

package com.example.demo.module.aspect;

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.*;

import org.springframework.stereotype.Component;

@Component

@Aspect

public class AdviceTest {

// 配置织入点

@Pointcut("execution(public * com.example.demo.module.aspect.Test.*(..))")

public void test(){

}

@Before("test()")

public void doBefore(JoinPoint joinPoint){

System.out.println(joinPoint.getSignature().getName() + "执行前置通知---");

}

@AfterReturning("test()")

public void doAfterSuccess(JoinPoint joinPoint){

System.out.println(joinPoint.getSignature().getName() + "执行返回通知---");

}

@AfterThrowing("test()")

public void doAfterError(JoinPoint joinPoint){

System.out.println(joinPoint.getSignature().getName() + "执行异常通知---");

}

@Around(value = "test()", argNames = "pjp")

public Object doAround(ProceedingJoinPoint pjp) {

Object[] args = pjp.getArgs();

Object result;

try {

// Before

System.out.println(pjp.getSignature().getName() + "环绕前置通知---");

result = pjp.proceed(args);

// AfterReturning

System.out.println(pjp.getSignature().getName() + "环绕返回通知---");

}catch (Throwable e){

// AfterThrowing

System.out.println(pjp.getSignature().getName() + "环绕异常通知---");

throw new RuntimeException(e);

}finally {

// After

System.out.println(pjp.getSignature().getName() + "环绕最终通知---");

}

return result;

}

@After("test()")

public void doAfter(JoinPoint joinPoint){

System.out.println(joinPoint.getSignature().getName() + "执行最终通知---");

}

}

添加测试方法:

package com.example.demo.module.aspect;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

@RequestMapping("test")

@RestController

public class Test {

@GetMapping("testMethod")

public void testMethod(){

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

}

}

运行结果:

测试异常通知,修改测试方法:

package com.example.demo.module.aspect;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

@RequestMapping("test")

@RestController

public class Test {

@GetMapping("testMethod")

public void testMethod(){

int i= 1/0;

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

}

}

运行结果:

通知执行顺序

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

@Before、@After、@AfterReturning、@AfterThrowing执行顺序

Spring 4.0

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

异常情况:@Before -> 目标方法 -> @After -> @AfterThrowingSpring 5.28

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

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

@Around的执行顺序

Spring 4.0

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

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

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

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

五大通知执行顺序

Spring 4.0

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

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

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

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

相关推荐

8年时间由2人攀升至2063人:中国俄罗斯族的前世今生
充电ic坏了(充电ic坏了换一个多少钱)
365招聘

充电ic坏了(充电ic坏了换一个多少钱)

📅 07-15 👁️ 6634
人民日报:假摔 真相在哪儿
365bet平台开户

人民日报:假摔 真相在哪儿

📅 09-14 👁️ 1021