Spring AOP(1)

AOP概述

AOP是Spring框架的第二大核心(第一大核心是IoC).

什么是AOP?

Aspect Oriented Programming(面向切面编程)

什么是面向切面编程呢? 切面就是指某一类特定的问题, 所以AOP也可以叫做面向特定方法编程

什么是面向特定方法编程呢?比如上一篇中讲到的拦截器, 就是对比如登录校验这一类问题的统一处理. 所以, 拦截器也算是AOP的一种应用. AOP是一种思想, 拦截器是AOP的一种实现. Spring框架实现了这种思想, 提供了拦截器技术的相关接口.

同样地, 统一数据返回格式和同意一场处理, 也是AOP思想的一种实现.

简单来说: AOP是一种思想, 是对某一类事情的集中处理.

什么是Spring AOP?

AOP是一种思想, 它的实现方法有很多, 有Spring AOP, 也有AspectJ, CGLIB等.

Spring AOP是其中的一种实现方式.

学会统一功能之后, 是不是就学会了AOP呢? 当然不是.

因为拦截器的作用维度是URL(一次请求和响应), @ControllerAdvice应用场景主要是全局异常处理(配合自定义异常效果更佳), 数据绑定, 数据预处理. AOP的作用维度更加细致(可以根据包, 类, 方法, 参数等进行拦截), 能够实现更加复杂的业务逻辑.

举个栗子:

我们现在有一个项目, 项目中开发了很多的业务功能:

 

现在有一些业务的执行业务比较低, 耗时比较长, 我们需要对接口进行优化.

第一步就需要定位出执行耗时比较长的业务方法, 再针对该业务方法来进行优化.

如何定位呢? 就需要统计当前项目中每一个业务方法的执行耗时.

如何统计呢? 可以在业务方法运行前和运行后, 记录下方法的开始时间和结束时间, 两者之差就是这个方法的耗时. 

这种方法是可以解决问题的, 但一个项目中会包含很多业务模块, 每个业务模块又有很多接口, 一个接口又包含很多方法, 如果我们要在每个业务方法上都这么整, 哥们愚公都没你能搬.

AOP就可以做到在不改动这些原始方法的基础上, 针对特定的方法进行功能的加强

AOP作用: 在程序运行期间在不修改源代码的基础上对已有方法进行增强(无侵入性:解耦)

Spring AOP快速入门

引入AOP依赖

在pom.xml文件中添加配置:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

编写AOP程序

记录每个Controller每个方法的执行时间(细节后面会讲).

@Slf4j
//需要被Spring管理
@Component
//spring使用了aspectJ的注解, 具体实现是Spring实现的. AspectJ是一个第三方的Jar包
@Aspect
public class TimeRecrodAspect {
    /**
     * 记录耗时
     */
    @Around("execution(* com.ashwakeup.demo.library.controller.*.*(..))")
    public Object timeRecord(ProceedingJoinPoint joinPoint) throws Throwable { //joinPoint可理解为目标方法
        //记录开始时间
        long start = System.currentTimeMillis();
        //执行目标方法
        Object proceed = joinPoint.proceed();
        //记录结束时间
        long end = System.currentTimeMillis();
        //日志打印耗时
        log.info("耗时时间: " + (end - start) + "ms");
        return proceed;
    }
}

运行程序, 观察日志:

 

对程序进行简单讲解:

1.@Aspect: 标识这是一个切面类.

2.@Around: 环绕通知, 在目标方法的前后都会执行. 后面的表达式表示对哪些方法进行增强.

3.ProceedingJoinPoint.proceed()让原始方法执行. 

 我们通过AOP入门程序完成了业务接口的执行耗时统计.

通过上面的程序, 我们也可以感受到AOP面向切面编程的优势:

代码无侵入: 主要是因为不修改原始的业务方法, 主要是对原始业务方法的功能进行增强.

减少代码重复

提高开发效率

维护方便

 Spring AOP详解

Spring AOP核心概念

切点(Pointcut)

Pointcut的作用就是提供一组规则, 告诉程序对哪些方法的功能进行增强.

这里的: @Around("execution(* com.ashwakeup.demo.library.controller.*.*(..))")就是切点表达式.

连接点(Join Point)

满足切点表达式规则的所有方法, 就是连接点. 也就是可以被AOP控制的方法,

比如上图, 就是指所有在com.ashwakeup.demo.library.controller下的所有方法都是连接点.

切点和连接点的关系: 连接点是满足切点表达式的元素. 切点可以看作是保存了众多连接点的一个集合.

eg:

切点表达式: 一班学生

连接点:张三, 李四.......

通知(Advice) 

通知就是指具体的工作, 指哪些重复的逻辑, 也就是共性功能(最终体现为一个方法).

比如上述程序中记录业务方法的耗时时间, 就是通知.

在AOP面向切面编程当中, 我们把这部分重复的代码逻辑抽取出来单独定义, 这部分代码就是通知的内容.

切面(Aspect)

切面(Aspect) = 切点(Pointcut) + 通知(Advice) 

通过切面就能描述当前AOP程序需要针对哪些方法, 在什么时候执行什么样的工作

切面既包含了通知逻辑的定义, 也包含了连接点的定义.

切面所在的类, 我们一般称为切面类(被@Aspect注解标识的类)

通知类型

上面讲了什么是通知, 接下来学习通知的类型. @Around就是其中一种通知类型, 表示环绕通知. Spring AOP的通知类型有以下几种:

@Around: 环绕通知, 此注解标注的通知方法在目标方法前后都会被执行

@Before: 前置通知, 此注解标注的通知方法在目标方法前被执行.

@After: 后置通知, 此注解标注的通知方法在目标方法后执行, 无论是否有异常都会被执行

@AfterReturning: 返回后通知, 此注解标注的通知方法在目标方法后执行, 有异常不会执行.

@AfterThrowing: 异常后通知, 此注解标注的通知方法发生异常后执行.

接下来通过代码来加深对这几个方法的理解:

@Slf4j
@Component
@Aspect
public class AspectDemo {
    //前置通知
    @Before("execution(* com.ashwakeup.demo.library.controller.TestController.*(..))")
    public void doBefore() {
        log.info("执行 Before 方法");
    }

    //后置通知
    @After("execution(* com.ashwakeup.demo.library.controller.TestController.*(..))")
    public void doAfter() {
        log.info("执行 After 方法");
    }

    //返回后通知
    @AfterReturning("execution(* com.ashwakeup.demo.library.controller.TestController.*(..))")
    public void doAfterReturning(){
        log.info("执行 AfterReturning 方法");
    }

    //抛出异常后通知
    @AfterThrowing("execution(* com.ashwakeup.demo.library.controller.TestController.*(..))")
    public void doAfterThrowing() {
        log.info("执行 AfterThrowing 方法");
    }

    //添加环绕通知
    @Around("execution(* com.ashwakeup.demo.library.controller.TestController.*(..))")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("Around方法开始时执行");
        Object result = joinPoint.proceed();
        log.info("Around方法结束后执行");
        return result;
    }
}

写一个测试程序:

@RestController
@RequestMapping("/test")
public class TestController {
    @RequestMapping("/t1")
    public String t1() {
        return "t1";
    }

    @RequestMapping("/t2")
    public boolean t2() {
        int a = 10 / 0;
        return true;
    }
}

 运行代码, 观察日志:

1.执行t1的情况:

程序正常运行的情况下, @AfterThrowing标识的通知方法并不会执行.

从上图可以看出: 执行逻辑大致为: Around上半-> Before -> AfterReturning -> After -> Around下半.

2.异常时的情况:

 程序发生异常的情况下:

@AfterReturning标识的通知方法不会执行, @AfterThrowing标识的通知方法执行了.

@Around环绕通知中原始方法调用时有异常, 通知中的环绕后的代码逻辑也不会在执行了(因为原始方法调用出异常了). 

执行逻辑: @Around上半 -> @Before -> @AfterThrowing -> @After

注意事项:

@Around环绕通知需要调用ProceedingJoinPoint.proceed()来让原始方法执行, 其它通知不需要考虑目标执行.

@Around环绕通知方法的返回值, 必须指定为Object, 来接收原始方法的返回值, 否则原始方法执行完毕, 是获取不到返回值的.

一个切面类有多个切点. 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/580050.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

windows无法启动Remote Desktop Services服务(位于本地计算机上) 错误2:系统找不到指定文件

在使用远程计算机时出现的错误&#xff0c;计算机在后台能正常打开&#xff0c;而无法使用远程连接&#xff0c;初步判定为远程服务问题&#xff0c;检查步骤如下&#xff1a; 一、检查计算机Remote Desktop Services服务 该服务是开启计算机远程时必要的服务&#xff0c;若该…

2024 年最好的免费数据恢复软件,您可以尝试的几个数据恢复软件

由于系统崩溃而丢失数据可能会给用户带来麻烦。我们将重要的宝贵数据和个人数据保存在我们的 PC、笔记本电脑和其他数字设备上。您可能会因分区丢失、意外删除文件和文件夹、格式化硬盘驱动器而丢失数据。数据丢失是不幸的&#xff0c;如果您不小心从系统中删除了文件或数据&am…

Vue3+Vite开发的项目进行加密打包

本文主要介绍Vue3+Vite开发的项目如何进行加密打包。 目录 一、vite简介二、混淆工具三、使用方法1. 安装插件:2. 配置插件:3. 运行构建:4. 自定义混淆选项:5. 排除文件:下面是Vue 3+Vite开发的项目进行加密打包的方法。 一、vite简介 Vite 是一个由 Evan You 创造的现代…

【Linux】进程信号 -- 详解

⚪前言 注意&#xff1a;进程间通信中的信号量跟下面要讲的信号没有任何关系。 一、从不同角度理解信号 1、生活角度的信号 你在网上买了很多件商品&#xff0c;在等待不同商品快递的到来。但即便快递没有到来&#xff0c;你也知道快递来临时&#xff0c;你该怎么处理快递&a…

Java设计模式 _结构型模式_桥接模式

一、桥接模式 1、桥接模式 桥接模式&#xff08;Bridge Pattern&#xff09;是一种结构型设计模式。用于把一个类中多个维度的抽象化与实现化解耦&#xff0c;使得二者可以独立变化。 2、实现思路 使用桥接模式&#xff0c;一定要找到这个类中两个变化的维度&#xff1a;如支…

基于Spring Boot的旅游管理系统设计与实现

基于Spring Boot的旅游管理系统设计与实现 开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 前台浏览管理界面图&#xff0c;通过内容列表可以获取网…

Git--多人协作

目录 一、多人协作一二、多人协作二三、 远程分⽀删除后&#xff0c;本地git branch -a依然能看到的解决办法 一、多人协作一 ⽬前&#xff0c;我们所完成的⼯作如下&#xff1a; 1.基本完成Git的所有本地库的相关操作&#xff0c;git基本操作&#xff0c;分⽀理解&#xff0c;…

适用于芯片行业的开发及管理工具:版本控制、持续集成、代码分析及项目管理工具介绍

3月28日-29日&#xff0c;2024国际集成电路展览会暨研讨会&#xff08;IIC Shanghai&#xff09;在上海成功举行。此次盛会汇聚了集成电路产业的众多领军企业&#xff0c;共同探寻和把握集成电路产业的发展脉络。 龙智携芯片研发及管理解决方案亮相展会&#xff0c;展示如何通…

遥感雷达波段的原理及应用

雷达波段是不同波长的组。每一种都有其独特的穿透地球表面的能力。它们还可以揭示环境的不同方面。 雷达频段在电磁频谱内具有特定的频率范围。这些波段由 L-、S-、C- 和 X-波段等字母表示。稍后会详细介绍这一点。 什么是合成孔径雷达&#xff1f; 合成孔径雷达 (SAR) 是一…

云原生Kubernetes: K8S 1.29版本 部署GitLab

目录 一、实验 1.环境 2.搭建NFS 3.K8S 1.29版本 部署Redis 4.K8S 1.29版本 部署Postgresql 5.K8S 1.29版本 部署GitLab 6.K8S 部署istio微服务 7.K8S 部署ingress应用路由 二、问题 1.K8S部署gitlab报错 2.gitlab创建失败 3.生成网关资源报错 4.安装istio 报错 …

PotatoPie 4.0 实验教程(30) —— FPGA实现摄像头图像中值滤波

中值滤波是什么&#xff1f; 图像的中值滤波是一种非线性图像滤波方法&#xff0c;它用于去除图像中的椒盐噪声或其他类型的噪声。中值滤波的原理是用每个像素周围的邻域中的中值来替代该像素的值。与均值滤波不同&#xff0c;中值滤波不会受到极端值的影响&#xff0c;因此在处…

FebHost:摩洛哥.ma域名注册介绍,规则有哪些?

摩洛哥国家域名介绍 摩洛哥是位于非洲西北部的一个国家&#xff0c;北部和西部面向地中海和大西洋&#xff0c;东部和南部则与阿尔及利亚、西撒哈拉和毛里塔尼亚接壤。摩洛哥的首都是拉巴特&#xff0c;但最大城市是卡萨布兰卡。摩洛哥的官方语言是阿拉伯语和柏柏尔语&#xf…

BTCOIN发布WEB3.0论坛:生态与金融的双重叙事热点驱动自由创新意识

在数字时代&#xff0c;信息的自由流动和透明度是推动经济发展和社会进步的关键。尤其在加密货币和区块链领域&#xff0c;这一点尤为重要。BTCOIN的最新创举——一个基于WEB3.0理念的信息论坛&#xff0c;不仅标志着信息传递自由化的新篇章&#xff0c;也为数字货币市场的信息…

聊聊.NET Core处理全局异常有那些方法

简述 处理全局异常的方法有IExceptionFilter&#xff08;异常处理&#xff09;&#xff0c;使用中间件异常处理&#xff0c;使用框架自带异常中间件等。考点 考察对异常处理方式的熟悉程度和广度&#xff0c;以及对中间件、过滤器熟练程度。 下面分别具体介绍三种处理异常的…

让华为设备跟上自动化的步伐,学会Python配置NETCONF,运维不再难!

在当今数字化时代&#xff0c;网络设备的自动化管理已经成为了不可或缺的趋势。对于华为设备的运维人员来说&#xff0c;学会利用Python配置NETCONF已经成为提高工作效率、降低运维成本的必备技能。本文将介绍如何利用Python和NETCONF来实现华为设备的自动化配置&#xff0c;让…

浅谈大数据时代下的电商风控||电商数据API接口

抢抢抢&#xff01;最后1天&#xff0c;双十一直播活动来啦&#xff01;抢直播专属优惠…… 视频号 随着大数据时代的兴起&#xff0c;互联网电商风控已经从无风控、人工抽取规则为主的简易规则模型发展到当前基于大数据的风控。与金融风控不同&#xff0c;互联网电商风控呈现出…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-3

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

红米K40手机刷机详解

了解什么是卡刷、什么是线刷 卡刷&#xff0c;就是把系统包放到你手机的SD卡&#xff0c;这一步&#xff0c;不用手机解BL锁&#xff0c;不用root&#xff0c;直接小米助手下载就可以刷。线刷就是用数据线连接电脑&#xff0c;通过XiaoMiFlash直接刷到手机&#xff0c;这一步权…

K8S深度解析:从入门到精通的全方位指南

目录 一、Kubernetes简介 二、Kubernetes的核心作用 三、Kubernetes架构图例 四、Kubernetes核心概念 Harbor仓库概述&#xff1a; Master----管理组件&#xff1a; API Server&#xff08;集群之心&#xff09;&#xff1a; Scheduler&#xff08;调度大师&…

27.统一网关Gateway-路由断言工厂

在配置文件中写的断言规则只是字符串&#xff0c;这些字符串会被Predicate Factory读取并处理&#xff0c;转变为路由判断的条件。 例如&#xff1a;Path /user/** 是按照路劲匹配&#xff0c;这个规则是由 org.springframework.cloud.gateway.handler.predicate.PathRouteP…