概述

本文通过案例讲解:@Aspect@Before@After@AfterReturning@AfterThrowing 注解的作用

尤其是:@Before@After@AfterReturning@AfterThrowing 注解的执行顺序

案例

使用注解的方式实现aop,实现 不修改 UserSrvImpl 源代码的情况下,增加打印日志的功能

创建maven工程

修改pom.xml

添加依赖

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.2.2.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
    </dependency>
</dependencies>

注解需要依赖 aspectjweaver

实现Controller

@RestController
public class StudentCtrl {

    @RequestMapping("/test")
    public JsonResult test() {
        System.out.println("test()");
        return new JsonResult(0,"执行成功!");
    }
}

实现Logger日志类

//由spring容器管理,该类不属于Controller、Service、Repository,所以用@Component注解
@Component
//表明该类为切面类
@Aspect
public class Logger {
    /*
    在 top.malaoshi.controller 包下的类 的 方法,都能注入代码
     */
    @Pointcut("execution(* top.malaoshi.controller.*.*(..))")
    public void pt(){
    }
    /*
    在 com.yingqi.service 包下的类 的 方法,执行之前 会先执行下面方法
     */
    @Before("pt()")
    public void beforePrint(){
        System.out.println("=======before");
    }
    /*
    在 com.yingqi.service 包下的类 的 方法,执行之后(不论是否抛异常) 会执行下面方法
     */
    @After("pt()")
    public void afterPrint(){
        System.out.println("======after");
    }
    /*
    在 com.yingqi.service 包下的类 的 方法,执行之后(没抛异常) 会执行下面方法
     */
    @AfterReturning("pt()")
    public void afterReturningPrint(){
        System.out.println("======afterReturning");
    }
    /*
    在 com.yingqi.service 包下的类 的 方法,执行之后(抛异常了) 会执行下面方法
     */
    @AfterThrowing("pt()")
    public void afterThrowingPrint(){
        System.out.println("======异常通知afterThrowingPrint");
    }
}

测试-执行成功

访问 Controller,执行结果如下:

=======before
test()
======after
======afterReturning

执行成功的通知顺序:

  1. before
  2. 目标方法
  3. after
  4. afterReturning

测试-执行报错

修改 Controller

test() 方法抛出异常:

@RequestMapping("/test")
public JsonResult test() {
    System.out.println("test()");
    int i=1/0;
    return new JsonResult(0,"执行成功!");
}

访问Controller,执行结果如下:

=======before
test()
======after
======异常通知afterThrowingPrint

执行报错的通知顺序:

  1. before
  2. 目标方法
  3. after
  4. afterThrowingPrint
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐