【JavaEE Spring】Spring AOP

Spring AOP

  • 1. AOP概述
  • 2. Spring AOP快速⼊⻔
    • 2.1 引⼊AOP依赖
    • 2.2 编写AOP程序
  • 3. Spring AOP详解
    • 3.1 SpringAOP核⼼概念
      • 3.1.1 切点(Pointcut)
      • 3.1.2 连接点(JoinPoint)
      • 3.1.3 通知(Advice)
      • 3.1.4 切⾯(Aspect)
    • 3.2 通知类型
    • 3.3 @PointCut
    • 3.4 切⾯优先级@Order
    • 3.5 切点表达式
      • 3.5.1 execution表达式
      • 3.5.2 @annotation
        • 3.5.2.1 ⾃定义注解@MyAspect
        • 3.5.2.2 切面类
        • 3.5.2.3 添加⾃定义注解
  • 4. Spring AOP原理
    • 4.1 代理模式
      • 4.1.1 静态代理
      • 4.1.2 动态代理

1. AOP概述

AOP是Spring框架的第⼆⼤核⼼(第⼀⼤核⼼是IoC)

  • 什么是 AOP?
    • AspectOrientedProgramming(⾯向切⾯编程)
    • 什么是⾯向切⾯编程呢?切⾯就是指某⼀类特定问题,所以AOP也可以理解为⾯向特定⽅法编程.
    • 简单来说: AOP是⼀种思想,是对某⼀类事情的集中处理
  • 什么是SpringAOP?
    • AOP是⼀种思想,它的实现⽅法有很多,有SpringAOP,也有AspectJ、CGLIB等.

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

AOP的作⽤:在程序运⾏期间在不修改源代码的基础上对已有⽅法进⾏增强(⽆侵⼊性:解耦)

2. Spring AOP快速⼊⻔

学习什么是AOP后,我们先通过下⾯的程序体验下AOP的开发,并掌握Spring中AOP的开发步骤.

需求:统计图书系统各个接⼝⽅法的执⾏时间.

2.1 引⼊AOP依赖

在pom.xml⽂件中添加配置

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

2.2 编写AOP程序

记录Controller中每个⽅法的执⾏时间

在这里插入图片描述
运⾏程序,观察⽇志
在这里插入图片描述
对程序进⾏简单的讲解:

  1. @Aspect:标识这是⼀个切⾯类
  2. @Around: 环绕通知,在⽬标⽅法的前后都会被执⾏.后⾯的表达式表⽰对哪些⽅法进⾏增强.
  3. ProceedingJoinPoint.proceed() 让原始⽅法执⾏

整个代码划分为三部分

在这里插入图片描述
我们通过AOP⼊⻔程序完成了业务接⼝执⾏耗时的统计.

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

  • 代码⽆侵⼊:不修改原始的业务⽅法,就可以对原始的业务⽅法进⾏了功能的增强或者是功能的改
  • 减少了重复代码
  • 提⾼开发效率
  • 维护⽅便

3. Spring AOP详解

下⾯我们再来详细学习AOP,主要是以下⼏部分

  • SpringAOP中涉及的核⼼概念
  • SpringAOP通知类型
  • 多个AOP程序的执⾏顺序

3.1 SpringAOP核⼼概念

3.1.1 切点(Pointcut)

切点(Pointcut), 也称之为"切⼊点"

Pointcut 的作⽤就是提供⼀组规则(使⽤AspectJpointcutexpressionlanguage来描述),告诉程序对哪些⽅法来进⾏功能增强.
在这里插入图片描述

3.1.2 连接点(JoinPoint)

满⾜切点表达式规则的⽅法,就是连接点.也就是可以被AOP控制的⽅法

以⼊⻔程序举例,所有
com.example.demo.controller
路径下的⽅法,都是连接点.

上述BookController中的⽅法都是连接点

切点和连接点的关系
连接点是满⾜切点表达式的元素.切点可以看做是保存了众多连接点的⼀个集合.

3.1.3 通知(Advice)

通知就是具体要做的⼯作,指哪些重复的逻辑,也就是共性功能(最终体现为⼀个⽅法)

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

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

3.1.4 切⾯(Aspect)

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

通过切⾯就能够描述当前AOP程序需要针对于哪些⽅法,在什么时候执⾏什么样的操作.

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

在这里插入图片描述
切⾯所在的类,我们⼀般称为切⾯类(被@Aspect注解标识的类)

3.2 通知类型

上⾯我们讲了什么是通知, 接下来学习通知的类型.
@Around 就是其中⼀种通知类型,表⽰环绕通知. Spring中AOP的通知类型有以下⼏种:

  • @Around:环绕通知,此注解标注的通知⽅法在⽬标⽅法前,后都被执⾏
  • @Before:前置通知,此注解标注的通知⽅法在⽬标⽅法前被执⾏
  • @After:后置通知,此注解标注的通知⽅法在⽬标⽅法后被执⾏,⽆论是否有异常都会执⾏
  • @AfterReturning: 返回后通知,此注解标注的通知⽅法在⽬标⽅法后被执⾏,有异常不会执⾏
  • @AfterThrowing:异常后通知,此注解标注的通知⽅法发⽣异常后执⾏
  1. 正常运⾏的情况

在这里插入图片描述
程序正常运⾏的情况下, @AfterThrowing
标识的通知⽅法不会执⾏从上图也可以看出来,
@Around 标识的通知⽅法包含两部分,⼀个"前置逻辑",⼀个"后置逻辑".其中"前置逻辑"会先于@Before 标识的通知⽅法执⾏,"后置逻辑"会晚于@After 标识的通知⽅法执⾏

在这里插入图片描述

  1. 异常时的情况
    在这里插入图片描述

注意事项:

  • @Around 环绕通知需要调⽤ ProceedingJoinPoint.proceed() 来让原始⽅法执⾏,其他通知不需要考虑⽬标⽅法执⾏.
  • @Around 环绕通知⽅法的返回值,必须指定为Object,来接收原始⽅法的返回值,否则原始⽅法执⾏完毕,是获取不到返回值的.
  • ⼀个切⾯类可以有多个切点.

3.3 @PointCut

在这里插入图片描述
上述代码就可以修改为:
在这里插入图片描述
当切点定义使⽤private修饰时,仅能在当前切⾯类中使⽤,当其他切⾯类也要使⽤当前切点定义时,就需要把private改为public.引⽤⽅式为:全限定类名.⽅法名()

在这里插入图片描述

3.4 切⾯优先级@Order

当我们在⼀个项⽬中,定义了多个切⾯类时,并且这些切⾯类的多个切⼊点都匹配到了同⼀个⽬标⽅法.当⽬标⽅法运⾏的时候,这些切⾯类中的通知⽅法都会执⾏,那么这⼏个通知⽅法的执⾏顺序是什么样的呢?

Spring 给我们提供了⼀个新的注解,来控制这些切⾯通知的执⾏顺序:@Order
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.5 切点表达式

上⾯的代码中,我们⼀直在使⽤切点表达式来描述切点.下⾯我们来介绍⼀下切点表达式的语法.

切点表达式常⻅有两种表达⽅式

  1. execution(…):根据⽅法的签名来匹配
  2. @annotation() :根据注解匹配

3.5.1 execution表达式

execution() 是最常⽤的切点表达式,⽤来匹配⽅法,语法为:

在这里插入图片描述
其中:访问修饰符和异常可以省略
在这里插入图片描述
在这里插入图片描述

3.5.2 @annotation

在这里插入图片描述
实现步骤:

  1. 编写⾃定义注解
  2. 使⽤@annotation 表达式来描述切点
  3. 在连接点的⽅法上添加⾃定义注解
3.5.2.1 ⾃定义注解@MyAspect

创建⼀个注解类(和创建Class⽂件⼀样的流程,选择Annotation就可以了)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.5.2.2 切面类

使⽤@annotation 切点表达式定义切点,只对@MyAspect ⽣效

切⾯类代码如下:在这里插入图片描述

3.5.2.3 添加⾃定义注解

在这里插入图片描述


Spring AOP 的实现方式

4. Spring AOP原理

上⾯我们主要学习了SpringAOP的应⽤,接下来我们来学习SpringAOP的原理,也就是Spring是如何实现AOP的.

Spring AOP是基于动态代理来实现AOP的,咱们学习内容主要分以下两部分

  1. 代理模式
  2. Spring AOP源码剖析

4.1 代理模式

代理模式,也叫委托模式.

定义:为其他对象提供⼀种代理以控制对这个对象的访问.它的作⽤就是通过提供⼀个代理类,让我们在调⽤⽬标⽅法的时候,不再是直接对⽬标⽅法进⾏调⽤,⽽是通过代理类间接调⽤.

在某些情况下,⼀个对象不适合或者不能直接引⽤另⼀个对象,⽽代理对象可以在客⼾端和⽬标对象之间起到中介的作⽤.

使⽤代理前:
在这里插入图片描述
使⽤代理后:

在这里插入图片描述
在这里插入图片描述

代理模式的主要⻆⾊

  1. Subject: 业务接⼝类.可以是抽象类或者接⼝(不⼀定有)
  2. RealSubject: 业务实现类. 具体的业务执⾏,也就是被代理对象.
  3. Proxy: 代理类.RealSubject的代理.

⽐如房屋租赁
Subject 就是提前定义了房东做的事情,交给中介代理,也是中介要做的事情
RealSubject: 房东
Proxy: 中介

UML类图如下:在这里插入图片描述
代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进⾏⼀些功能的附加与增强.
根据代理的创建时期,代理模式分为静态代理和动态代理.

  • 静态代理:由程序员创建代理类或特定⼯具⾃动⽣成源代码再对其编译,在程序运⾏前代理类的.class ⽂件就已经存在了.
  • 动态代理:在程序运⾏时,运⽤反射机制动态创建⽽成.

4.1.1 静态代理

静态代理:在程序运⾏前,代理类的.class⽂件就已经存在了.在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上⾯这个代理实现⽅式就是静态代理(仿佛啥也没⼲).

从上述程序可以看出,虽然静态代理也完成了对⽬标对象的代理,但是由于代码都写死了,对⽬标对象的每个⽅法的增强都是⼿动完成的,⾮常不灵活. 所以⽇常开发⼏乎看不到静态代理的场景

4.1.2 动态代理

相⽐于静态代理来说,动态代理更加灵活.

我们不需要针对每个⽬标对象都单独创建⼀个代理对象,⽽是把这个创建代理对象的⼯作推迟到程序运⾏时由JVM来实现.也就是说动态代理在程序运⾏时,根据需要动态创建⽣成.

⽐如房屋中介,我不需要提前预测都有哪些业务,⽽是业务来了我再根据情况创建.

Java也对动态代理进⾏了实现,并给我们提供了⼀些API,常⻅的实现⽅式有两种:

  1. JDK动态代理
  2. CGLIB动态代理

动态代理在我们⽇常开发中使⽤的相对较少,但是在框架中⼏乎是必⽤的⼀⻔技术.学会了动态代理之后,对于我们理解和学习各种框架的原理也⾮常有帮助.

JDK动态代理

JDK动态代理类实现步骤

  1. 定义⼀个接⼝及其实现类(静态代理中的HouseSubject 和RealHouseSubject )
  2. ⾃定义InvocationHandler 并重写 invoke⽅法在invoke ⽅法中我们会调⽤⽬标⽅法(被代理类的⽅法)并⾃定义⼀些处理逻辑
  3. 通过Proxy.newProxyInstance(ClassLoader loader,Class<?>[]
    interfaces,InvocationHandler h) ⽅法创建代理对象

在这里插入图片描述
在这里插入图片描述
CGLIB动态代理

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


Spring 默认使用的代理方法如下

在这里插入图片描述

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

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

相关文章

什么是网络数据抓取?有什么好用的数据抓取工具?电商数据API免费测试入口

什么是网络数据抓取 网络数据抓取&#xff08;Web Scraping&#xff09;是指采用技术手段从大量网页中提取结构化和非结构化信息&#xff0c;按照一定规则和筛选标准进行数据处理&#xff0c;并保存到结构化数据库中的过程。目前网络数据抓取采用的技术主要是对垂直搜索引擎&a…

Maya------布尔 圆形圆角组件

17. maya常用命令7.布尔 圆形圆角组件_哔哩哔哩_bilibili 选中一个模型&#xff0c;再按shift加选另外一个模型 圆形圆角命令

QT5.14+VS2017安装踩过的一些坑

1.在QT中使用MSVC只能用VS2017&#xff0c;相应的调试器的版本只能用15.9&#xff0c;高于15.9的亲测都不行。完整的安装除了需要QT5.15和VS2017&#xff0c;还需要Windows SDK (10.0.22621) 下载地址&#xff1a;https://developer.microsoft.com/zh-cn/windows/downloads/win…

Qt读写Execl:QXlsx库

Qt三方库开发技术&#xff1a;QXlsx介绍、编译和使用 我自己记录的实例代码&#xff1a;https://download.csdn.net/download/cao_jie_xin/88795216 目录 一、概述二、下载三、编译四、加载QXlsx静态库五、介绍一些常用的功能1、一些头文件和命名空间2、创建一个excel文件3、…

消息中间件之RocketMQ源码分析(四)

消费者的Rebalance机制 客户端是通过Rebalance服务做到高可靠的。当发生Broker掉线、消费者实例掉线、 Topic扩容等各种突发情况时&#xff0c;消费者组中的消费者实例是怎么重平衡的&#xff0c;以支持全部队列的正常消费的? Rebalance服务的类图 RebalanceImpl的核心属性 …

CHS_06.2.3.4_2+用信号量实现进程互斥、同步、前驱关系

CHS_06.2.3.4_2用信号量实现进程互斥、同步、前驱关系 知识总览信号量机制实现进程互斥信号量机制实现进程同步信号量机制实现前驱关系 知识回顾 各位同学 大家好 在这个小节中 我们要学习怎么用信号量机制来实现进程的同步互制关系 知识总览 那么 我们之前学习了互斥的几种软…

【C++杂货铺】详解类和对象 [下]

个人博客&#xff1a;代码菌-CSDN博客 专栏&#xff1a;C杂货铺_代码菌的博客-CSDN博客 目录 &#x1f308;前言&#x1f308; &#x1f4c1; 初始化列表&#xff08;灰常重要&#xff09; &#x1f4c2; 引入 &#x1f4c2; 概念 &#x1f4c2; 特性 &#x1f4c1; 拓展构…

OG Trade在ZKX揭幕:一家基于Starknet的游戏化永续合约交易所

ZKX的 OG Trade通过内置游戏化和30分钟交易竞赛&#xff0c;为所有交易者创造机会&#xff0c;革新了永续合约交易模式。 2024年1月30日 — ZKX宣布推出OG Trade&#xff0c;这是一家基于Starknet的游戏化永续合约交易所&#xff0c;旨在满足短期交易者、高水平交易者和波段交易…

021 while循环详解

什么时while循环 int i 0; // 循环输出i&#xff0c;大于100时结束 while(i < 100){System.out.println(i);i; } int i 0; int sum 0; // 计算1-100的和&#xff0c;输出 while(i < 100){sum i;i; } System.out.println(sum); 什么是死循环 循环没有停止下来的条件…

Vue3嵌套ref小细节,自我解惑

前言&#xff1a; 作者在学习时&#xff0c;遇到代码如下&#xff1a; import { ref,watch } from vue const state ref({count:0}) const addState ()>{state.value.count } 对于方法中对对象中count的理解存在偏差 问题及解决&#xff1a; 误解&#xff1a; 认为是…

面对近期行情大起大落的伦敦银需要关注什么?

近期经常有听到投资者抱怨说&#xff0c;伦敦银价格没有明显趋势&#xff0c;很难做。确实&#xff0c;我们从日线图看&#xff0c;金价处于一个比较宽幅的横盘区间当中&#xff0c;近期的行情也是大涨大跌。投资者认为&#xff0c;面对大起大落的行情无从下手。下面我们就来讨…

会话管理技术

会话管理 会话管理是跟踪用户跨网页活动的过程。以在线购物商场为例。用户可以选择产品并将其添加到购物车中。用户转到其他页面时,购物车中仍然保留详细信息,以便用户查看购物车中的物品并下订单。 会话跟踪也可用于跟踪用户的偏好。例如,如果用户选择了多本小说,则向用…

内网安全:RDP WinRS WinRM SPN Kerberos 横向移动

目录 WinRM协议 RDP协议 域横向移动&#xff1a;RDP协议 RDP协议利用 一. 探针服务 二. 获取NTML Hash 明文密码 三. 连接执行 域横向移动&#xff1a;WinRM WinRS WinRM协议、WinRS命令利用 一. cs 内置端口扫描5985 二. 连接执行 三. 上线CS 四. CS插件横向移动…

基于springboot+vue的阿博图书馆管理系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目背景…

Springboot项目基础配置:小白也能快速上手!

推荐文章 给软件行业带来了春天——揭秘Spring究竟是何方神圣&#xff08;一&#xff09; 给软件行业带来了春天——揭秘Spring究竟是何方神圣&#xff08;二&#xff09; 给软件行业带来了春天——揭秘Spring究竟是何方神圣&#xff08;三&#xff09; 给软件行业带来了春天—…

vue-cli项目运行流程介绍

一、前言 ​ 本文介绍 vue-cli搭建的项目运行流程&#xff0c;基于已经搭建好的基础项目。关于 vue-cli 构建项目的详细流程&#xff0c;可参考博文&#xff1a;使用vue脚手架构建项目 二、main.js 项目运行 会加载入口文件 main.js /* html文件中&#xff0c;通过script …

CTF盲水印工具:Blind-WaterMark安装

工具下载地址&#xff1a;GitCode - 开发者的代码家园 下载完毕后&#xff0c;只留这些东西就行 接下来需要安装两个依赖&#xff1a; opencv、matplotlib 直接pip install安装的话&#xff0c;工具使用会报错 所以需要到网站里挑选适合的版本进行安装 下载地址&#xff1…

DrissionPage多线程实践

DrissionPage多线程实践 背景&#xff1a;项目中需要抓取部分平台的数据&#xff0c;因为涉及到登录&#xff0c;且暂未实现接口登录。所以采用selenium登录后获取cookie传给requests的方式来实现。后了解到DrissionPage国产开源库&#xff0c;等于是把selenium和requests结合起…

部署YUM仓库服务

一、yum仓库 1. yum简介 yum是一个基于RPM包&#xff08;是Red-Hat Package Manager红帽软件包管理器的缩写&#xff09;构建的软件更新机制&#xff0c;能够自动解决软件包之间的依赖关系。 为什么会有依赖关系的发生 因为linux本身就是以系统简洁为自身优势&#xff0c;所以…

大数据信用报告应该去哪里查询比较好呢?

对于个人而言&#xff0c;大数据信用报告也变得越来越重要。那么&#xff0c;大数据信用报告应该去哪里查询呢?本文将为您详细介绍征信和大数据的区别&#xff0c;并推荐一个可靠的大数据平台。 首先&#xff0c;我们需要了解征信和大数据的区别 征信报告 依法采集、整理、保存…