Spring AOP(JavaEE进阶系列5)

目录

前言:

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.mzph.cn/news/97051.shtml

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

相关文章

element ui中父子组件共用一个el-dialog弹窗,切换组件页面弹窗进行关闭

在Element UI中&#xff0c;如果多个父子组件共用一个el-dialog弹窗&#xff0c;并且需要在切换组件页面时关闭弹窗&#xff0c;你可以考虑以下方法来实现&#xff1a; 使用Vuex进行状态管理&#xff1a; 在Vuex中创建一个状态来管理弹窗的显示状态&#xff08;例如&#xff0…

NOSQL Redis 数据持久化 RDB、AOF(二) 恢复

redis 执行flushall 或 flushdb 也会产生dump.rdb文件&#xff0c;但里面是空的。 注意&#xff1a;千万执行&#xff0c;不然rdb文件会被覆盖的。 dump.rdb 文件如何恢复数据 讲备份文件 dump.rdb 移动到redis安装目录并启动服务即可。 dump.rdb 自动触发 和手动触发 自…

【GIT版本控制】--项目管理与工具

一、使用Git与项目管理工具的集成 将Git与项目管理工具集成在一起可以有效地跟踪和管理软件开发项目。以下是如何使用Git与项目管理工具&#xff08;如GitHub、GitLab、Bitbucket和Jira&#xff09;进行集成的关键方法&#xff1a; 创建问题或任务&#xff1a; 项目管理工具通…

IDEA 2023.1.3图文安装教程及下载

IDEA 2023.1 最新变化是在 IDEA 2023.1 中&#xff0c;对新 UI 做出了大量改进。实现了性能增强&#xff0c;从而更快导入 Maven&#xff0c;以及在打开项目时更早提供 IDE 功能。 新版本通过后台提交检查提供了简化的提交流程。 IntelliJ IDEA Ultimate 现在支持 Spring Secur…

智慧电力物联网系统引领电力行业数字化发展

智慧电力物联网系统是以提高用户侧电力运行安全、降低运维成本为目的的一套电力运维管理系统。综合分析采用智慧物联网、人工智能等现代化经济信息网络技术&#xff0c;配置智能采集终端、小安神童值班机器人或边缘网关&#xff0c;实现对企事业用户供配电系统的数字化远程监控…

Elasticsearch:使用 ELSER 文本扩展进行语义搜索

在今天的文章里&#xff0c;我来详细地介绍如何使用 ELSER 进行文本扩展驱动的语义搜索。 安装 Elasticsearch 及 Kibana 如果你还没有安装好自己的 Elasticsearch 及 Kibana&#xff0c;请参考如下的链接来进行安装&#xff1a; 如何在 Linux&#xff0c;MacOS 及 Windows 上…

Opengl之立方体贴图

简单来说,立方体贴图就是一个包含了6个2D纹理的纹理,每个2D纹理都组成了立方体的一个面:一个有纹理的立方体。你可能会奇怪,这样一个立方体有什么用途呢?为什么要把6张纹理合并到一张纹理中,而不是直接使用6个单独的纹理呢?立方体贴图有一个非常有用的特性,它可以通过一…

【计算机视觉|人脸建模】学习从图像中回归3D面部形状和表情而无需3D监督

本系列博文为深度学习/计算机视觉论文笔记&#xff0c;转载请注明出处 标题&#xff1a;Learning to Regress 3D Face Shape and Expression from an Image without 3D Supervision 链接&#xff1a;[1905.06817] Learning to Regress 3D Face Shape and Expression from an I…

Mac迁移的时候,如何同步启动台图标布局

北京 当迁移MacOS数据到另一台电脑的时候&#xff08;或者用时间机器还原重置前的电脑状态的时候&#xff09;&#xff0c;有少数地方是不同步的&#xff0c;其中&#xff0c;启动台布局就是一个&#xff0c;这点看似不重要&#xff0c;实际上还是对于之前对App位置的记忆丢失还…

OpenCV实现求解单目相机位姿

单目相机通过对极约束来求解相机运动的位姿。参考了ORBSLAM中单目实现的代码&#xff0c;这里用opencv来实现最简单的位姿估计. mLeftImg cv::imread(lImg, cv::IMREAD_GRAYSCALE); mRightImg cv::imread(rImg, cv::IMREAD_GRAYSCALE); cv::Ptr<ORB> OrbLeftExtractor …

云服务器CVM_云主机_云计算服务器_弹性云服务器-腾讯云

腾讯云服务器CVM提供安全可靠的弹性计算服务&#xff0c;腾讯云明星级云服务器&#xff0c;弹性计算实时扩展或缩减计算资源&#xff0c;支持包年包月、按量计费和竞价实例计费模式&#xff0c;CVM提供多种CPU、内存、硬盘和带宽可以灵活调整的实例规格&#xff0c;提供9个9的数…

Go 存储系列:B+树存储引擎 boltdb

boltdb 介绍 boltdb是一个纯go编写的支持事务的文件型单机kv数据库 支持事务&#xff1a; boltdb数据库支持两类事务&#xff1a;读写事务、只读事务。这一点就和其他kv数据库有很大区别文件型&#xff1a; boltdb所有的数据都是存储在磁盘上的&#xff0c;所以它属于文件型数…

服务器连接时间长了,忘记密码,解密密码

一、选中连接地址&#xff0c;右键导出 二、打开导出的配置文件&#xff0c;搜索password&#xff0c;找到password的编码后的字符串复制 三、main()方法的字符串替换成复制的password编码 import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import …

mysql面试题22:SQL优化的一般步骤是什么,怎么看执行计划(explain),如何理解其中各个字段的含义

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:SQL优化的一般步骤是什么,怎么看执行计划(explain),如何理解其中各个字段的含义 SQL优化的一般步骤如下: 分析和理解问题:首先,要确保对问…

代码随想录二刷 Day 30

78.子集 与组合问题不同的就是要收集所有的子节点&#xff0c;而不仅仅的叶子节点&#xff1b;唯一一行代码的区别就是要把result的收集过程放到递归程序的最开始那里 class Solution { public:vector<vector<int>> result;vector<int> path;void traversa…

Reactor 模式网络服务器【I/O多路复用】(C++实现)

前导&#xff1a;本文是 I/O 多路复用的升级和实践&#xff0c;如果想实现一个类似的服务器的话&#xff0c;需要事先学习 epoll 服务器的编写。 友情链接&#xff1a; 高级 I/O【Linux】 I/O 多路复用【Linux/网络】&#xff08;C实现 epoll、select 和 epoll 服务器&#x…

线性表的线性表示;初始化,输出,插入,删除,查找;

#include <iostream> #include <algorithm>//fill() #define InitSize 5using namespace std;/*线性表&#xff1a;线性表示&#xff1b;初始化&#xff0c;输出&#xff0c;插入&#xff0c;删除&#xff0c;查找*///静态分配数组 typedef struct{int data[InitSi…

频敏变阻器 BP4G-31511/06350 BP4G-25010/04563 结构简单、操作方便

BP4G系列频敏变阻器&#xff08;以下简称BP4G&#xff09;适用于14-1000KW绕线型异步感应电机作重载偶尔起动用。它具有结构简单、操作方便、维护容易等优点&#xff0c;是一种理想的电动机起动装置 BP4G系列频敏变阻器(以下简称BP4G)适用于14-1000KW绕线型异步感应电机作重载…

[0xGame 2023] week1

整理一下&#xff0c;昨天该第二周了。今天应该9点结束提交&#xff0c;等我写完就到了。 PWN 找不到且不对劲的flag 第1题是个nc测试&#xff0c;但也不完全是&#xff0c;因为flag在隐含目录里 高端的syscall 程序使用了危险函数&#xff0c;并且没有canary阻止&#xff0…

第1次 更多的bash shell命令

1.检测程序 程序都是进程在运行&#xff0c;进程里面有很多线程&#xff0c;面试经常会问进程和线程的区别&#xff0c;线程可以访问另一个线程的什么什么的&#xff0c;这些我都听腻了&#xff0c;区别就是进程会分配程序需要的空间&#xff0c;创建线程需要的资源&#xff0c…