AOP-简介五种通知

本文深入探讨Spring AOP(面向切面编程)的实际应用,详细解释了如何使用各种通知类型,如@Before、@After、@AfterReturning和@AfterThrowing,以及环绕通知@Around。通过一个具体的案例,演示了如何在方法调用前后执行特定操作,处理异常,并获取方法的参数和返回值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先随便写个方法,index静态变量的作用是便于验证抛异常情况。

@RestController
public class indexController {

    private static int index =1;

    @RequestMapping("/index")
    public String index(String name,String age) throws Exception {
        index++;
        int i = index % 2;
        if(i==1)throw new Exception("抛出异常");
        System.out.println("index()");
        return "Nice day-index()";
    }
    
}

先简介一下注解

@Aspect - 定义一个切面,意思就是用这个注解的类,现在就是一个切面

@Component - spring的注解,意思是当前类交给spring容器来管理了。

@Poincut  - 切入点,简单来说就是与你要作用的对象或方法所匹配上,execution( * *(..)),*代表任何,第一个* 代表返回值,意思任何返回值的方法,第二个*代表类名意思所有的类也可以精确到方法,(..),代表参数要是精确到参数就在()里定义 ..两个点代表任何参数。

例子中含义是,任何返回值 并且在com.hfl.web.controller.indexController类下的,叫index并且参数随意的方法。先看下例子在做通知的介绍。


@Aspect
@Component
public class LogAop {

    @Pointcut("execution(* com.hfl.web.controller.indexController.index(..))")
    public void aop(){}

    /**
     * 前置通知 - 获取参数名称
     * @param joinPoint
     */
    @Before(value = "aop()")
    public void before(JoinPoint joinPoint){
        List<Object> objects = Arrays.asList(joinPoint.getArgs());
        System.out.println("前置通知--参数:"+objects);
    }

    /**
     * 后置通知 - 异常依旧可以执行,获取不到返回值
     * @param joinPoint
     */
    @After("aop()")
    public void after(JoinPoint joinPoint){
        String method = joinPoint.getSignature().getName();
        System.out.println("后置通知--方法名称:"+method);
    }

    /**
     * 后置增强通知 - 异常不执行,可以获取返回值
     * @param joinPoint
     * @param ret
     */
    @AfterReturning(value = "aop()",returning = "ret")
    public void afterReturning(JoinPoint joinPoint,Object ret){
        String method_name = joinPoint.getSignature().getName();
        System.out.println("后置增强通知--方法名称:"+method_name+"--返回值:"+ret);
    }

    /**
     * 后置异常通知 - 当抛出异常后可以获取异常信息
     * @param joinPoint
     * @param ex
     */
    @AfterThrowing(value = "aop()",throwing = "ex")
    public void afterException(JoinPoint joinPoint,Exception ex){
        String method_name = joinPoint.getSignature().getName();
        System.out.println("后置异常通知--方法名称:"+method_name+"--异常:"+ex);
    }


}

 

@Before - 为前置通知: 可以获取到方法的参数 通过JoinPoint.getArgs()方法来获取,参数数组

@After - 为后置通知:后置通知有个特点是不管抛不抛出异常都执行。但是获取不到返回值这个通知

@AfterReturning - 后置增强通知:可以获取到方法的返回值,若改方法抛出异常时,该通知不执行。

@AfterThrowing - 后置异常通知:当方法抛出异常后才执行的通知,可以获取异常信息.

测试======

请求一次http://localhost:8080/index?name=bob&age=18,注意观察循序,因为没有抛出异常所有没有异常通知。

第二次请求,因为抛出异常,所以出现异常通知,但是后置增强通知也回不触发。

接下来是第五种通知

@Around - 环绕通知 简单来说就是4种通知的结合体,

/**
     * 环绕通知
     * @param joinPoint
     * @return
     */
    @Around("aop()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("环绕通知开始");
        Object[] args = joinPoint.getArgs();//参数
        String method_name = joinPoint.getSignature().getName();//方法名
        Object proceed = null;
        try {
            System.out.println("前置通知--参数:"+ Arrays.asList(args));

            proceed = joinPoint.proceed(args);//执行该方法

            System.out.println("后置通知--方法名称:"+method_name);
        } catch (Throwable throwable) {

            System.out.println("后置异常通知--异常:"+throwable.getMessage());
            throw throwable;
        }
        System.out.println("后置增强通知--方法名称:"+method_name+"--返回值:"+proceed);
        System.out.println("环绕通知结束");
        return proceed;
    }

测试  第一次请求,

第二次请求

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值