【JavaEE】面向切面编程AOP是什么-Spring AOP框架的基本使用

【JavaEE】Spring AOP(1)

在这里插入图片描述

文章目录

  • 【JavaEE】Spring AOP(1)
    • 1. Spring AOP 是什么
      • 1.1 AOP 与 Spring AOP
      • 1.2 没有AOP的世界是怎样的
      • 1.3 AOP是什么
    • 2. Spring AOP 框架的学习
      • 2.1 AOP的组成
        • 2.1.1 Aspect 切面
        • 2.1.2 Pointcut 切点
        • 2.1.3 Advice 通知
        • 2.1.4 Join Point 连接点
      • 2.2 Spring AOP的基本使用
        • 2.2.1 引入依赖
        • 2.2.2 定义一个Aspect
        • 2.2.3 定义一个Pointcut
        • 2.2.4 Join Point
        • 2.2.5 定义Advice
          • 2.2.5.1 前置通知,后置通知与返回通知
          • 2.2.5.2 异常通知
          • 2.2.5.3 环绕通知
      • 2.3 Spring AOP的实现原理
        • 2.3.1 动态代理
        • 2.3.2 Spring AOP动态代理组成
        • 2.3.3 JDK Proxy 与 CGLIB的区别

【JavaEE】Spring AOP(1)

1. Spring AOP 是什么

1.1 AOP 与 Spring AOP

AOP (**A**spect **O**riented Programming),是一种思想,即面向切面编程

Spring AOP 则是一个框架,Spring项目中需要引入依赖而使用

  • AOP和Spring AOP的关系就相当于IoC和DI
  • Spring AOP让开发者能够半自动的开发AOP思想下实现的功能

1.2 没有AOP的世界是怎样的

我们要实现用户登录校验的功能,没有实现AOP之前,我们只能这样做:

博客系统登录功能实现,博客传送门:【JavaEE】前后端综合项目-博客系统(下)_s:103的博客-CSDN博客

  1. 前端进入每一个页面的时候,专门发送“登录校验”的请求给后端进行登录校验
  2. 前端发送每一个请求的时候,后端都会自动进行登录校验

无论是哪种,都有这样的特性,就是代码耦合度高,网页的每个功能都要各自实现“登录校验”的代码,这样的坏处是:

  1. 不符合专一设计原则,开发者开发一个功能就应该全心全意,有针对性,这样开发效率也会高点儿~
  2. 耦合度很高,一改则需万改

图示:

在这里插入图片描述

1.3 AOP是什么

刚才说了,AOP是面向切面编程,这是英语直译的结果,不用太多理会~

  • 可以理解为,它是 对某一类事情的集中处理

有了AOP后,我们只需要在代码的某一处配置一下,所有的功能就能实现用户登录校验了,不再需要重复写那些代码了~

  • 也对“登录校验”这个步骤,集中处理了,这个代码开发过程就是面向切面编程

切面可以理解为,切下来的一个方面,一个步骤

切下来后有种藕断丝连的感觉:

藕断丝连 的图像结果

在这里插入图片描述

例如这个图,再等一下讲解AOP的组成之后,回头看可能会有更好的理解~

  • AOP后,功能表现还是左上,但是代码长成右下
  • “登录校验”被切了下来一样

如果把切面看成动作执行者,✂

  • 我们可以将切面形象地比喻为一把剪刀。
  • 剪刀可以在不改变原始材料的情况下,将其切割成不同的形状
  • 同样,切面在编程中也可以在不修改原始代码的情况下,将横切关注点应用到不同的对象或方法上
    • 在代码实现的时候,将需要的统一处理的功能,“剪”下来进行统一处理
  • 就像剪刀可以将材料切割成不同的形状一样,切面可以将横切关注点切割并应用到代码的不同部分,从而实现代码的模块化和重用

例如,调用功能1的时候,会通过切下来的“面”的匹配对应的“块”,之后进行“组装”~

  • 这样就在调用功能1之前进行了登录校验

好处:

  1. 满足单一设计原则,登录校验的存在,不会改变各个功能的原代码
  2. 耦合度低,改一处等于改一万处

AOP就很适合解决这种功能统一,且是使用的地方较多的功能了

  • AOP的统一处理!

除了登录校验外,还可以实现:

  • 统一
    1. 日志记录
    2. 方法执行时间统计
    3. 返回格式设置
    4. 异常处理
    5. 事务开启与提交
    6. 等等…

也可以说,AOP面向了多个对象

也就是说,AOP是OOP(Object Oriented Programming,面向对象编程)的一个补充和完善

2. Spring AOP 框架的学习

Spring AOP框架内部实现了AOP,开发者按照规则写下的代码,就对应着AOP逻辑

Spring AOP的学习分为以下三步:

  1. AOP的组成
  2. Spring AOP的基本使用
  3. Spring AOP的实现原理

2.1 AOP的组成

2.1.1 Aspect 切面

一个Aspect代表一个“统一处理”,因为统一设计原则,一个切面就是一个功能,例如“登录校验”

  • 包含切点、通知,即有横切逻辑的定义,也有连接点的定义

如果把这些定义,看成“切面”的独一无二的横切面,看成标识,切面就对应那个“块”,也就是功能,所以切面就看成一个功能~

即,AOP是干啥的

2.1.2 Pointcut 切点

规定 这个切面是从哪些,前后端交互接口,“剪”下来的

  • 例如:定义用户登录拦截规则,哪些接口才需要判断用户登录权限

2.1.3 Advice 通知

AOP执行的具体方法

  • 例如:获取用户信息,如果后端有记录对应的登录信息,就说明已经登录,否则没有登录

2.1.4 Join Point 连接点

有可能触发切点的所有点

  • 满足切点规则的所有前后端交互接口

2.2 Spring AOP的基本使用

通过代码实现,你可能会有更切合的体验!

  • 我只讲一种方式,其他感兴趣的可以去学,有需要的去学

2.2.1 引入依赖

你会发现,在IDEA的勾选选入依赖里,没有AOP这个选项,这也很正常,因为并不是所有依赖都包含在其中!

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

在这里插入图片描述

  • 第一次加载会有点慢,注意网络通畅~

2.2.2 定义一个Aspect

在这里插入图片描述

一个切面其实就是一个类,加上@Aspect注解,这个类就是为了实现某个“统一处理”的

  • 需要加五大类注解,这个算是个组键吧,所以用@Component

2.2.3 定义一个Pointcut

在这里插入图片描述

一个方法加上注解@Pointcut,在括号内写一些语句,就定义了一个切点

  • 这个方法可以不返回一切,方法名自定义,没有参数列表,没有代码体…,如果加了会怎么样感兴趣可以去了解,但是暂时用不到~
  • 括号内部的语句是有对应的语法的,这里了解这句话的含义,举一反三就好,语法是啥感兴趣可以去了解

execution(* com.example.demo.controller.TestController.*(..)),解析:

  1. execution(),执行括号中提及的方法,就触发切点
  2. *,不限制方法权限(public、private…),全部方法
  3. com.example.demo.controller.TestController.,针对的类的位置
  4. *(..),代表类中的所有方法
    1. *,所有的方法名
    2. (..),任意的参数列表

2.2.4 Join Point

对于连接点,则是刚才切点对应的前后端交互接口:

  1. /test/say_hi
  2. /test/say_hello

我们在这里不需要在意其他业务,只需要专注开发,而Aspect的代码开发里则面向了这几个连接点!

在这里插入图片描述

为了与通知的方法区分,我在控制台打印信息:

在这里插入图片描述

2.2.5 定义Advice

通知就是访问对应接口的时候,要执行的业务,分为五种通知:

  1. 前置通知
  2. 后置通知
  3. 环绕通知
  4. 返回通知
  5. 异常通知

顾名思义,区分就是,通知执行的时机~

对应五种注解(加在一个方法的上面,此方法被称为通知方法):

  1. @Before,通知方法在目标方法执行之前执行
  2. @After,通知方法在目标方法执行之后执行
  3. @Around,通知包裹了目标方法,自定义行为
  4. @AfterReturning,通知方法在目标方法返回后调用
  5. @AfterThrowing,通知方法在目标抛出异常后调用
2.2.5.1 前置通知,后置通知与返回通知
// 前置通知
@Before("pointcut()")
public void doBefore(){System.out.println("执⾏ Before ⽅法");
}
// 后置通知
@After("pointcut()")
public void doAfter(){System.out.println("执⾏ After ⽅法");
}
// return 之前通知
@AfterReturning("pointcut()")
public void doAfterReturning(){System.out.println("执⾏ AfterReturning ⽅法");
}

注解括号内代表,对应的切点方法

效果:

在这里插入图片描述

按多次:

在这里插入图片描述

2.2.5.2 异常通知
// 抛出异常之前通知
@AfterThrowing("pointcut()")
public void doAfterThrowing(){System.out.println("执⾏ doAfterThrowing ⽅法");
}

对于异常通知的触发案例,暂时不介绍

2.2.5.3 环绕通知

自定义行为的通知,可以模拟其他通知~

@Around("pointcut()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {Object object = null;System.out.println("Around方法开始执行");object = joinPoint.proceed();System.out.println("Around方法结束执行");return object;
}

ProceedingJoinPoint这个类的对象joinPoint,代表着连接点对象

  • 调用proceed()方法代表进行这个连接点对于的方法
    • try catch后能模拟异常通知

记得返回这个object,不然框架处理不了返回值作为响应!

  • 默认执行后的返回值是交给框架的,而这里是交给object~

效果:

在这里插入图片描述

这样也看出了优先级~

环绕通知,更灵活

  • 更好的实现“原子性”,通过加锁就行,如执行时间统计…

  • 如后置通知方法需要跟前置通知方法有“数据交互”

2.3 Spring AOP的实现原理

Spring AOP 是构建在**动态代理的基础上,因此Spring 对 AOP的支持局限于方法级的拦截**

2.3.1 动态代理

原本访问目标对象:

在这里插入图片描述

AOP之后:

在这里插入图片描述

就像fiddler一样,代理了请求,期间保留了其信息…

通过代理类,目标对象Join Point何时执行目标方法,代理说了算

  • 在环绕通知的时候体现尤为显著
  • 代理类 根据 Aspect 进行对应的行为

我们不通过Spring AOP框架,我们只能自己实现AOP才能实现在目标方法调用之前和调用之后…时机进行一些业务!

2.3.2 Spring AOP动态代理组成

  1. JDK Proxy
    • 代理类必须实现某个接口,才能使用JDK Proxy
    • 底层有用到反射…
  2. CGLIB
    • 通过实现代理类的子类来实现动态代理,只能代理能被继承的类

通过这两种动态代理的实现~

  • 单独一种有局限性

2.3.3 JDK Proxy 与 CGLIB的区别

  1. 出身不同
    • JDK Proxy 来自java
    • CGLIB 来自第三方
  2. 实现不同
    • JDK Proxy,通过代理类必须实现某个接口
    • CGLIB,通过实现代理类的子类
  3. 性能不同
    • jdk 7/7+,JDK Proxy性能略高于CBLIB
    • jdk7-,CBLIB性能远高于JDK Proxy

文章到此结束!谢谢观看
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭🦆

不得不提的是,切面、切点、连接点、通知,这些名词,不要纠结他们为啥这么叫,咱们知道他们的含义,知道Spring AOP怎么开发就行了~

代码:spring_aop-demo · 游离态/马拉圈2023年8月 - 码云 - 开源中国 (gitee.com)


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【算法日志】贪心算法刷题:单调递增数列,贪心算法总结(day32)

代码随想录刷题60Day 目录 前言 单调递增数列 贪心算法总结 前言 今天是贪心算法刷题的最后一天&#xff0c;今天本来是打算刷两道题&#xff0c;其中的一道hard题做了好久都没有做出来(主要思路错了)。然后再总结一下。 单调递增数列 int monotoneIncreasingDigits(int n…

CST HFSS MATLAB参数方程定义曲面绘制

CST HFSS 函数定义曲面绘制 简介环境HFSSCSTMATLAB 简介 若在柱坐标系中半径r随z和phi都会变&#xff0c;无法使用一般的方法绘制&#xff0c;这时可以使用参数方程定义的曲面来绘制。举一个例子如下&#xff0c; r 100 0.5 ( c o s ( 0.2 ∗ p i ∗ z ) − 1 ) c o s ( φ …

初识网络原理(笔记)

目录 ​编辑局域网 网络通信基础 IP 地址 端口号 协议 协议分层 TCP / IP 五层网络模型 网络数据传输的基本流程 发送方的情况&#xff1a; 接收方的情况 局域网 搭建网络的时候&#xff0c;需要用到 交换机 和 路由器 路由器上&#xff0c;有 lan 口 和 wan 口 虽…

苍穹外卖 day2 反向代理和负载均衡

一 前端发送的请求&#xff0c;是如何请求到后端服务 前端请求地址&#xff1a;http://localhost/api/employee/login 路径并不匹配 后端接口地址&#xff1a;http://localhost:8080/admin/employee/login 二 查找前端接口 在这个页面上点击f12 后转到networ验证&#xff0…

K8s学习笔记4

场景&#xff1a; 项目研发部门最近要进行应用运行基础环境迁移&#xff0c;需要由原先的虚拟机环境迁移到K8s集群环境中&#xff0c;以便应对开发快速部署和快速测试的需要&#xff0c;因此&#xff0c;需要准备一套可以用于开发需求的K8s集群&#xff0c;但是对于仅有容器基…

Redis企业级解决方案

缓存预热 “ 宕机 ” 服务器启动后迅速宕机 问题排查 1. 请求数量较高 2. 主从之间数据吞吐量较大&#xff0c;数据同步操作频度较高 , 因为刚刚启动时&#xff0c;缓存中没有任何数据 解决方案 准备工作&#xff1a; 1. 日常例行统计数据访问记录&#xff0c;统计访…

Docker的基本使用

Docker 概念 Docker架构 docker分为客户端&#xff0c;Docker服务端&#xff0c;仓库 客户端 Docker 是一个客户端-服务器&#xff08;C/S&#xff09;架构程序。Docker 客户端只需要向 Docker 服务端发起请求&#xff0c;服务端将完成所有的工作并返回相应结果。 Docker …

Midjourney API 国内申请及对接方式

在人工智能绘图领域&#xff0c;想必大家听说过 Midjourney 的大名吧&#xff01; Midjourney 以其出色的绘图能力在业界独树一帜。无需过多复杂的操作&#xff0c;只要简单输入绘图指令&#xff0c;这个神奇的工具就能在瞬间为我们呈现出对应的图像。无论是任何物体还是任何风…

(排序) 剑指 Offer 51. 数组中的逆序对 ——【Leetcode每日一题】

❓剑指 Offer 51. 数组中的逆序对 难度&#xff1a;困难 在数组中的两个数字&#xff0c;如果前面一个数字大于后面的数字&#xff0c;则这两个数字组成一个逆序对。输入一个数组&#xff0c;求出这个数组中的逆序对的总数。 示例 1: 输入: [7,5,6,4] 输出: 5 限制&#xff…

铜矿人员定位安全方案

针对铜矿中的人员定位安全需求&#xff0c;可以采用以下方案&#xff1a; 1.实时人员定位系统&#xff1a;建立一个实时人员定位系统&#xff0c;通过在矿工的工作服或安全帽上安装UWB或RFID定位设备&#xff0c;以及相应的接收器和基站&#xff0c;实时跟踪和定位矿工的位置。…

设计模式——桥接模式

引用 桥我们大家都熟悉&#xff0c;顾名思义就是用来将河的两岸联系起来的。而此处的桥是用来将两个独立的结构联系起来&#xff0c;而这两个被联系起来的结构可以独立的变化&#xff0c;所有其他的理解只要建立在这个层面上就会比较容易。 基本介绍 桥接模式&#xff08;Br…

ceph集群的扩容缩容

文章目录 集群扩容添加osd使用ceph-deploy工具手动添加 添加节点新节点前期准备新节点安装ceph&#xff0c;出现版本冲突 ceph-deploy增加节点 集群缩容删除osd删除节点 添加monitor节点删除monitor节点使用ceph-deploy卸载集群 实验所用虚拟机均为Centos 7.6系统&#xff0c;8…

Spring5学习笔记—AOP编程

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; Spring专栏 ✨特色专栏&#xff1a; M…

完美解决微信小程序van-field left-icon自定义图片

实现效果&#xff1a; <view class"userName"><van-field left-icon"{{loginUserNameIcon}}" clearable class"fieldName" value"{{ loginUserName }}" placeholder"请输入账号" border"{{ false }}" &g…

APP上线为什么要提前部署安全产品呢?

一般平台刚上线或者日活跃量比较高的时候&#xff0c;很容易成为攻击者的目标&#xff0c;服务器如果遭遇黑客攻击&#xff0c;资源耗尽会导致平台无法访问&#xff0c;业务也无法正常开展&#xff0c;服务器一旦触发黑洞机制&#xff0c;就会被拉进黑洞很长一段时间&#xff0…

数据结构 - 线性表的定义和基本操作

一、定义 线性表是具有相同特性的数据元素的一个有限序列。 线性表&#xff1a; 由n(n≥0)个数据元素&#xff08;结点&#xff09;组成的有限序列。线性表中数据元素是一对一的关系&#xff0c;每个结点最多有一个直接前驱&#xff0c;和一个直接后继 二、线性表的基本操作 …

GNU GRUB version 2.06 Minimal Bash-lke line editing is supported 问题修复

一、问题背景 博主喜欢折腾系统&#xff0c;电脑原来有一个windows系统&#xff0c;想整一个Linux双系统&#xff0c;结果开机时出现以下画面&#xff1a; GNU GRUB version 2.06 Minimal Bash-lke line editing is supported. TAB lists possible comand completions, Anywh…

【学会动态规划】 最长递增子序列(26)

目录 动态规划怎么学&#xff1f; 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 写在最后&#xff1a; 动态规划怎么学&#xff1f; 学习一个算法没有捷径&#xff0c;更何况是学习动态规划&#xff0c; 跟我…

【从零开始学爬虫】采集中国国际招标网招标数据

l 采集网站 【场景描述】采集中国国际招标网招标数据。 【源网站介绍】中国国际招标网致力于为企业提供招标、采购、拟在建项目信息及网上招标采购等一系列商务服务。 【使用工具】前嗅ForeSpider数据采集系统 http://www.forenose.com/view/forespider/view/download.html 【…

Azure CLI 进行磁盘加密

什么是磁盘加密 磁盘加密是指在Azure中对虚拟机的磁盘进行加密保护的一种机制。它使用Azure Key Vault来保护磁盘上的数据&#xff0c;以防止未经授权的访问和数据泄露。使用磁盘加密&#xff0c;可以保护磁盘上的数据以满足安全和合规性要求。 参考文档&#xff1a;https://l…