泪伤荡的编程指南 泪伤荡的编程指南
首页
  • 基础篇
  • 集合篇
  • 并发篇
  • JVM篇
  • 新特性
  • 进阶篇
  • 网络
  • 操作系统
  • 数据结构与算法
  • 硬件
  • 基础篇
  • MySql
  • Oracle
  • PostgreSQL
  • 达梦
  • Redis
  • Mongodb
  • Hive
  • 数据库比较
  • Spring
  • SpringMvc
  • SpringBoot
  • Hibernate
  • iBatis
  • Mybatis
  • Mybatis-plus
  • Mybatis-plus-join
  • 各个框架对比
  • UML画图
  • 设计须知
  • 开发流程
  • 开发理论
  • 架构体系
  • 设计模式
  • 开源知识
  • 分布式解决方案
  • SpringCloud
  • API网关
  • 注册中心
  • 配置中心
  • 服务调用
  • 分布式事务
  • 消息队列
  • 调度作业
  • 链路追踪
  • 服务保障
  • 搜索引擎Elk
  • 安全框架
  • 监控体系
  • 部署容器
  • Netty
  • Tomcat
  • Nginx
  • 图片云存储
  • 云存储
  • 虚拟机Linux
  • 项目部署
  • 容器部署
  • 开发工具篇
  • 工具库篇
  • 开发技巧篇
  • 工具类系列
  • Bug记录仓库
  • 随笔
  • HTML与CSS
  • JS学习
  • Vue3入门
  • Vue3进阶
  • 黑马Vue3
  • 视频网站
  • 音乐网站
  • 商城网站
  • 论坛网站
  • scrm项目
  • Yudao-cloud
  • RuoYi-Vu-cloud
  • 博客搭建
  • 网站收藏箱
  • 断墨寻径摘录
  • 费曼学习法
  • Java术语
  • 命名英语
  • 业务英语
  • 表字段英语
  • 包名英语
Github (opens new window)
首页
  • 基础篇
  • 集合篇
  • 并发篇
  • JVM篇
  • 新特性
  • 进阶篇
  • 网络
  • 操作系统
  • 数据结构与算法
  • 硬件
  • 基础篇
  • MySql
  • Oracle
  • PostgreSQL
  • 达梦
  • Redis
  • Mongodb
  • Hive
  • 数据库比较
  • Spring
  • SpringMvc
  • SpringBoot
  • Hibernate
  • iBatis
  • Mybatis
  • Mybatis-plus
  • Mybatis-plus-join
  • 各个框架对比
  • UML画图
  • 设计须知
  • 开发流程
  • 开发理论
  • 架构体系
  • 设计模式
  • 开源知识
  • 分布式解决方案
  • SpringCloud
  • API网关
  • 注册中心
  • 配置中心
  • 服务调用
  • 分布式事务
  • 消息队列
  • 调度作业
  • 链路追踪
  • 服务保障
  • 搜索引擎Elk
  • 安全框架
  • 监控体系
  • 部署容器
  • Netty
  • Tomcat
  • Nginx
  • 图片云存储
  • 云存储
  • 虚拟机Linux
  • 项目部署
  • 容器部署
  • 开发工具篇
  • 工具库篇
  • 开发技巧篇
  • 工具类系列
  • Bug记录仓库
  • 随笔
  • HTML与CSS
  • JS学习
  • Vue3入门
  • Vue3进阶
  • 黑马Vue3
  • 视频网站
  • 音乐网站
  • 商城网站
  • 论坛网站
  • scrm项目
  • Yudao-cloud
  • RuoYi-Vu-cloud
  • 博客搭建
  • 网站收藏箱
  • 断墨寻径摘录
  • 费曼学习法
  • Java术语
  • 命名英语
  • 业务英语
  • 表字段英语
  • 包名英语
Github (opens new window)
  • Spring

    • Spring基础小结
    • 聊聊Spring IoC 和 AOP
    • AOP实战
      • 常见注解
        • @Aspect
        • @Pointcut
        • @Before
        • @After
        • @AfterReturning
        • @AfterThrowing
        • @Around
      • 环绕通知是如何判定前后的?
        • 执行前(Before)
        • 执行后(After)
        • 异常处理
      • 学习参考
    • 元注解知识小结
    • SpringCache小记
    • 异步注解相关
  • SpringBoot

    • SpringBoot核心知识总结
    • 配置文件详解
    • SpringBoot3知识汇总
    • SpringBoot参数校验注解解析
    • SpringBoot读取Resource下文件的几种方式
  • Mybatis

    • Mybatis基础知识小结
    • Mybatis映射文件解析
    • 获取中文字符串首字母
  • 常用框架
  • Spring
泪伤荡
2024-04-01
目录

AOP实战

# AOP 实战

# 常见注解

# @Aspect

  • 用于定义一个切面,将横切逻辑封装在切面中。

  • 切面是包含切入点和通知的类。

  • 示例代码:

    @Aspect
    @Component
    public class LoggingAspect {
        // 切面类的实现
    }
    
    1
    2
    3
    4
    5

# @Pointcut

  • 用于定义一个切入点,指定在哪些连接点上应用切面逻辑。

  • 可以在多个通知中重复使用同一个切入点。

  • 示例代码:

    @Pointcut("execution(* com.example.service.*.*(..))")
    private void serviceLayer() {}
    
    1
    2

# @Before

  • 用于定义一个前置通知,在方法执行之前执行切面逻辑。

  • 在连接点之前执行。

  • 示例代码:

    @Before("serviceLayer()")
    public void beforeAdvice() {
        // 执行前置通知逻辑
    }
    
    1
    2
    3
    4

# @After

  • 用于定义一个后置通知,在方法执行之后执行切面逻辑(无论方法是否抛出异常)。

  • 在连接点之后执行。

  • 示例代码:

    @After("serviceLayer()")
    public void afterAdvice() {
        // 执行后置通知逻辑
    }
    
    1
    2
    3
    4

# @AfterReturning

  • 用于定义一个返回后通知,在方法正常返回后执行切面逻辑。

  • 只在方法正常返回时执行,在方法抛出异常时不执行。

  • 示例代码:

    @AfterReturning(pointcut = "serviceLayer()", returning = "result")
    public void afterReturningAdvice(Object result) {
        // 执行返回后通知逻辑
    }
    
    1
    2
    3
    4

# @AfterThrowing

  • 用于定义一个异常通知,在方法抛出异常后执行切面逻辑。

  • 只在方法抛出异常时执行,在方法正常返回时不执行。

  • 示例代码:

    @AfterThrowing(pointcut = "serviceLayer()", throwing = "exception")
    public void afterThrowingAdvice(Exception exception) {
        // 执行异常通知逻辑
    }
    
    1
    2
    3
    4

# @Around

  • 用于定义一个环绕通知,在方法执行前后执行切面逻辑,并控制方法的执行。

  • 在连接点之前和之后执行。

  • 示例代码:

    @Around("serviceLayer()")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        // 执行前置逻辑
        Object result = joinPoint.proceed(); // 执行被通知的方法
        // 执行后置逻辑
        return result;
    }
    
    1
    2
    3
    4
    5
    6
    7

# 环绕通知是如何判定前后的?

在使用 AOP 的环绕通知(@Around)时,你可以通过 ProceedingJoinPoint 对象的 proceed() 方法来决定是执行前还是执行后。

  • proceed() 方法的作用是:执行被通知(advice)的目标方法。

以下是如何控制执行时机的详细说明:

# 执行前(Before)

在调用 proceed() 方法之前,你可以执行任何你需要在目标方法执行之前的逻辑。这通常包括验证、设置上下文信息、记录日志等。例如:

public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable {
    // 执行前的逻辑,例如权限检查
    checkPermission(authCheck);

    try {
        // 继续执行目标方法
        return joinPoint.proceed();
    } catch (Throwable e) {
        // 异常处理逻辑
        handleException(e);
        throw e;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

在这个例子中,checkPermission 方法会在目标方法执行前被调用,用于进行权限检查。如果权限检查通过,joinPoint.proceed() 会被调用,从而执行目标方法。

# 执行后(After)

目标方法的执行可以在 proceed() 方法调用后被认为是“执行后”。一旦 proceed() 方法被调用,目标方法就会开始执行。目标方法执行完成后,你可以在 proceed() 方法之后执行任何清理或后续操作。例如:

public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable {
    try {
        // 执行前的逻辑
        checkPermission(authCheck);
        // 执行目标方法
        return joinPoint.proceed();
    } catch (Throwable e) {
        // 异常处理逻辑
        handleException(e);
        throw e;
    } finally {
        // 执行后的逻辑,无论目标方法是否成功执行都会执行
        cleanupResources();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

在这个例子中,cleanupResources 方法会在 proceed() 方法调用之后执行,无论目标方法是否成功执行。这使得 finally 块成为执行清理逻辑的理想位置。

# 异常处理

如果在目标方法执行过程中抛出异常,你可以在 catch 块中捕获并处理这些异常。这允许你在方法执行后进行异常处理,同时仍然可以在 finally 块中执行清理逻辑。

总结一下,通过控制 proceed() 方法的调用时机,你可以在目标方法执行前后执行自定义的逻辑。使用 AOP 的环绕通知提供了一种灵活的方式来在方法执行的不同阶段插入横切关注点。

# 学习参考

  • 8000字涵盖几乎所有的springboot注解以及详解!! - 掘金 (juejin.cn) (opens new window)
上次更新: 2024/10/26 02:01:17
聊聊Spring IoC 和 AOP
元注解知识小结

← 聊聊Spring IoC 和 AOP 元注解知识小结→

Theme by Vdoing | Copyright © 2024-2025 泪伤荡 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式