Spring AOP(JavaEE进阶系列5)

news2025/2/25 16:57:10

目录

前言:

1.什么是Spring AOP

2.为什么要使用AOP呢?

3.AOP的组成

3.1切面

3.2切点

3.3通知

3.4连接点

4.Spring AOP的实现

4.1添加依赖

4.2定义切面

4.3定义切点

4.4实现通知

5.AOP的实现原理

结束语:


前言:

在上一节中小编主要是于大家分享了有关于MyBatis的一些基础知识,让大家了解了有关于如何将数据库和我们的程序进行关联,那么接下来我们就来一起来学一下有关于AOP的一些知识,在Spring中一般提到的就是IoC和AOP,那么之前的学习中也给大家介绍了有关于IoC容器的一些基础知识,那么接下来小编将会带着大家一起来学习有关于AOP的一些基础知识。这节中小编将主要介绍有关于AOP的组成,概念,学习Spring AOP的使用以及Spring AOP的实现原理。

1.什么是Spring AOP

在介绍Spring AOP之前,首先我们需要了解一下什么是AOP?

AOP(Aspect Oriented Programming):面向切面编程,它是一种思想,它是对某一类事情的集中处理。比如用户登录权限的校验,没学AOP之前,我们所有需要判断用户登录的页面(中的方法),都要各自实现或调用用户验证的方法,然而有了AOP之后,我们只需要在某一处配置一下,所有需要判断用户登录页面中的方法就全部可以实现用户登录验证了,不再需要每个方法中都写相同的用户登录验证了。

那么对于AOP与Spring AOP之间的关系就是:AOP是一种思想,而Spring AOP是一个框架,提供了一种对AOP思想的实现,它们的关系和IoC与DI类似。

2.为什么要使用AOP呢?

想象⼀个场景,我们在做后台系统时,除了登录和注册等几个功能不需要做⽤户登录验证之外,其他几乎所有⻚⾯调⽤的前端控制器( Controller)都需要先验证⽤户登录的状态,那这个时候我们要怎么处理呢?
我们之前的处理⽅式是每个 Controller 都要写⼀遍⽤户登录验证,然⽽当你的功能越来越多,那么你要 写的登录验证也越来越多,⽽这些⽅法⼜是相同的,这么多的⽅法就会代码修改和维护的成本。那有没有简单的处理⽅案呢?答案是有的,对于这种功能统⼀,且使⽤的地⽅较多的功能,就可以考虑 AOP 来统⼀处理了。
除了统⼀的⽤户登录判断之外,AOP 还可以实现:
  • 统⼀⽇志记录
  • 统⼀⽅法执⾏时间统计
  • 统⼀的返回格式设置
  • 统⼀的异常处理
  • 事务的开启和提交等
也就是说使⽤ AOP 可以扩充多个对象的某个能力,所以 AOP 可以 说是 OOP(Object Oriented
Programming,⾯向对象编程)的补充和完善。

3.AOP的组成

3.1切面

切面(Aspect):它是定义事件(表明AOP是做啥的)。比如现在要做一个用户的登录校验。他就像是一个公司的老板一样来定义公司的方向。

3.2切点

切点(Pointcut):它是用来定义具体规则的。在上面切面明确了要做的是用户的登录校验之后接下来就由切点来定义用户登录拦截规则,哪些接口判断用户登录权限。哪些不判断。就像是公司中的中层领导人一样制定一份具体的方案。

3.3通知

通知(Advice):AOP执行的具体方法。在前俩个的基础之上方向明确,方案已经制定好之后,那么接下来就需要实施了,获取用户登录的信息,如果获取到说明已经登录,否则未登录。他就是公司的底层,用来负责具体业务的执行。

在Spring切面类中,可以在方法上使用以下注解,会设置方法为通知方法,在满足条件之后会通知本方法进行调用:

  • 前置通知:使用@Before,通知方法会在目标方法调用之前执行。
  • 后置通知:使用@After,通知方法会在目标方法返回或者抛出异常后调用。
  • 返回通知:使用@AfterReturning,通知方法会在目标方法返回后调用。
  • 异常通知:使用@AfterThrowing,通知方法会在目标方法抛出异常之后调用。
  • 环绕通知:使用@Around,通知包裹了被通通知的方法,在被通知的方法之前和调用方法之后执行自定义的行为。

3.4连接点

连接点( Join Point):有可能触发切点的所有点。比如说是在登录功能中会触发登录功能的所有接口。
AOP整个组成部分的概念如下图所示:

4.Spring AOP的实现

先来定义一个UserController。

package com.example.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/getuser")
    public String getUser() {
        System.out.println("do getUser");
        return "get user";
    }

    @RequestMapping("/deluser")
    public String delUser() {
        System.out.println("do delUser");
        return "del user";
    }
}

4.1添加依赖

在pom.xml中添加如下配置。

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

4.2定义切面

4.3定义切点

4.4实现通知

当我们输入一下url的时候:
就会在控制台中输出前置通知。

当加上后置通知的时候就会如下所示:

后置通知的代码:

 

此时在输入url之后的效果就是:

 

那么如果加的是环绕通知的效果呢?

环绕通知的代码如下所示:

 

执行结果如下所示:

 

那么如果没有上述的这些拦截的话,在实现过程当中就不会执行任何其他操作,比如我们现在定义一个ArticleController,如下所示:

package com.example.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/art")
public class ArticleController {
    @RequestMapping("/getart")
    public String getArticle(){
        System.out.println("do getArticle");
        return "getArticle";
    }
}

当我们在访问的是后台就只会执行它本身要执行的方法。

  

5.AOP的实现原理

Spring AOP 是构建在动态代理基础上,因此 Spring 对 AOP 的⽀持局限于⽅法级别的拦截。

Spring AOP ⽀持 JDK ProxyCGLIB ⽅式实现动态代理。默认情况下,实现了接⼝的类,使用 AOP 会基于 JDK ⽣成代理类,没有实现接⼝的类,会基于 CGLIB ⽣成代理类。

Spring 动态代理的组成:

  • JDK Proxy:代理对象必须实现接口,才能使用JDK Proxy。
  • CGLIB:通过实现代理类的子类来实现动态代理,注意被final修饰的类是不能够被代理的。

JDK Proxy 与 CGLIB的区别:

  • 出生不同。
  • 实现不同:JDK Proxy要求代理类实现接口才能实现代理;而CGLIB是通过实现代理类的子类来完成动态代理的。
  • 性能不同:JDK& + JDK Proxy性能是略高于CGLIB;JDK7之前CGLIB性能高于JDK Proxy。

结束语:

好了这节小编就给大分享到这里啦,希望这节对大家有关于Spring AOP的基础知识的了解有一定帮助,想要学习的同学记得关注小编和小编一起学习吧!如果文章中有任何错误也欢迎各位大佬及时为小编指点迷津(在此小编先谢过各位大佬啦!)

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

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

相关文章

光伏VSG-基于虚拟同步发电机的光伏并网逆变器系统(Simulink仿真)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

EfficientNetV2:更快、更小、更高精度

一、说明 EfficientNets是目前最强大的卷积神经网络&#xff08;CNN&#xff09;模型之一。随着视觉变压器的兴起&#xff0c;它实现了比高效网络更高的精度&#xff0c;出现了CNN现在是否正在消亡的问题。EfficientNetV2 不仅通过提高准确性&#xff0c;还通过减少训练时间和延…

Linux系统之部署h5ai目录列表程序

Linux系统之部署h5ai目录列表程序 一、h5ai介绍1.1 h5ai简介1.2 h5ai特点 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、检查本地环境3.1 检查本地操作系统版本3.2 检查系统内核版本 四、安装httpd软件4.1 检查yum仓库4.2 安装httpd软件4.3 启动httpd服务4.4 查看htt…

rabbitmq查看节点信息命令失败

不影响访问rabbitmq&#xff0c;但是无法使用 命令查看节点信息 等 查看节点信息命令&#xff1a;rabbitmq-diagnostics status --node rabbitJHComputer Error: unable to perform an operation on node ‘rabbitJHComputer‘. Please see diagnostics informatio rabbitmq-…

C++内存管理:其二、数组内存管理

一、new一个对象数组 如果我们想在堆内存上创建一个对象数组&#xff0c;可以这么写&#xff1a; Complex * pca new Complex[3]; 主要做三件事&#xff1a; &#xff08;1&#xff09;申请一块内存&#xff0c;足够放置三个Complex对象。 &#xff08;2&#xff09;执行三次…

(一)实现一个简易版IoC容器【手撸Spring】

一、前言 相信大家在看本篇文章的时候&#xff0c;对IoC应该有一个比较清晰的理解&#xff0c;我在这里再重新描述下&#xff1a;它的作用就是实现一个容器将一个个的Bean&#xff08;这里的Bean可以是一个Java的业务对象&#xff0c;也可以是一个配置对象&#xff09;统一管理…

无需公网IP,教学系统如何实现远程一站式管理维护?

全国多所高校应用红亚科技研发的一套教学实验系统平台&#xff0c;此实验系统服务器分别部署在学校内部&#xff0c;与校内的各种教学资源整合在一起&#xff0c;向校内师生提供服务。 红亚总部设立在北京&#xff0c;虽说在全国22个省会均设有办事处&#xff0c;在面对全国多…

MM-Camera架构-Preview 流程分析

目录 文章目录 1 log开的好&#xff0c;问题都能搞2 lib3 preview3.1 打开视频流3.1.1 cpp\_module\_start\_session3.1.2 cpp\_thread\_create3.1.3 cpp\_thread\_funcsundp-3.1 cpp\_hardware\_open\_subdev(ctrl->cpphw)sundp-3.2 cpp\_hardware\_process\_command(ctrl-…

ssm+vue的劳务外包管理系统(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的劳务外包管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

3BHB003154R0101 GVC707AE01 3BHB003149P201 3BHB003149P104 5SXE05-0156

3BHB003154R0101 GVC707AE01 3BHB003149P201 3BHB003149P104 5SXE05-0156 特征 IT/OT SOC是一种安全监控服务&#xff0c;它使用快速、可扩展和统一的下一代安全信息和事件管理(SIEM)。该服务使用各种CTI和ML工具从客户的IT/OT设备收集事件日志&#xff0c;以检测网络攻击、…

leetCode 300.最长递增子序列 (贪心 + 二分 ) + 图解 + 优化 + 拓展

300. 最长递增子序列 - 力扣&#xff08;LeetCode&#xff09; 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff…

Kafka 高可用

正文 一、高可用的由来 1.1 为何需要Replication 在Kafka在0.8以前的版本中&#xff0c;是没有Replication的&#xff0c;一旦某一个Broker宕机&#xff0c;则其上所有的Partition数据都不可被消费&#xff0c;这与Kafka数据持久性及Delivery Guarantee的设计目标相悖。同时Pr…

算法通关村第17关【青铜】| 贪心

贪心算法&#xff08;Greedy Algorithm&#xff09;是一种常见的算法设计策略&#xff0c;通常用于解决一类优化问题。其核心思想是&#xff1a;在每一步选择中都采取当前状态下的最优决策&#xff0c;从而希望最终能够达到全局最优解。贪心算法不像动态规划算法需要考虑各种子…

电暖产品经营小程序商城搭建

电暖产品的需求度很高&#xff0c;包括地暖系统及壁挂炉、水暖散热器等&#xff0c;尤其每年冬天&#xff0c;部分家庭或办公场所就会有相关需求&#xff0c;庞大市场下为电暖各领域商家及品牌带来了商机。 然而随着互联网深入各行业及实体店生意难做&#xff0c;无论品牌还是…

安卓RecycleView包含SeekBar点击列表底部圆形阴影处理

seekbar在列表中点击底部圆形阴影禁止显示方法 大家好&#xff0c;最近写了自定义的seekbar实现显示进度值&#xff0c;然而呢&#xff0c;我的seekbar控件是作为recycleview的item来使用的&#xff0c;我设置了禁止点击和滑动方法如下&#xff1a; seekBar.setOnTouchListene…

ubuntu使用whisper和funASR-语者分离-二值化

文章目录 一、选择系统1.1 更新环境 二、安装使用whisper2.1 创建环境2.1 安装2.1.1安装基础包2.1.2安装依赖 3测试13测试2 语着分离创建代码报错ModuleNotFoundError: No module named pyannote报错No module named pyannote_whisper 三、安装使用funASR1 安装1.1 安装 Conda&…

SpringBoot+MinIO实现对象存储

一、 MinIO MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口&#xff0c;非常适合于存储大容量非结构化的数据&#xff0c;例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等&#xff0c;而一个对象文件可以是任意大小&#…

【好玩】如何在github主页放一条贪吃蛇

前言 &#x1f34a;缘由 github放小蛇&#xff0c;就问你烧不烧 起因看到大佬github上有一条贪吃蛇扭来扭去&#xff0c;觉得好玩&#xff0c;遂给大家分享一下本狗的玩蛇历程 &#x1f95d;成果初展 贪吃蛇 &#x1f3af;主要目标 实现3大重点 1. github设置主页 2. git…

Arcgis日常天坑问题(1)——将Revit模型转为slpk数据卡住不前

这段时间碰到这么一个问题&#xff0c;revit模型在arcgis pro里导出slpk的时候&#xff0c;卡在98%一直不动&#xff0c;大约有两个小时。 首先想到的是revit模型过大&#xff0c;接近300M。然后各种减小模型测试&#xff0c;还是一样的问题&#xff0c;大概花了两天的时间&am…

OpenHarmony父子组件双项同步使用:@Link装饰器

子组件中被Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。 说明&#xff1a; 从API version 9开始&#xff0c;该装饰器支持在ArkTS卡片中使用。 概述 Link装饰的变量与其父组件中的数据源共享相同的值。 装饰器使用规则说明 Link变量装饰器 说明 装饰器参数 无…