切面编程的理解和使用,Java小白入门(五)

我们进入ruoyi-framework,立刻看到的内容

了解一下aspectj 这个概念

概念

面向切面编程(AOP)

面向切面编程(AOP)是一种编程范式,重点聚焦于软件应用程序中的关注点分离。AOP 背后的思想是软件应用程序具有多个切面,其中一些切面跨越了模块化编码的典型划分,就是可能多个模块化代码都会使用,导致代码分散和混乱。

在软件开发中,有些功能包括日志记录、安全检查、错误处理和数据验证。在面向对象编程 (OOP) 等传统编程范式中,这些横切关注点通常与核心业务逻辑纠缠在一起,导致代码难以维护和扩展。

AOP(Aspect Oriented Programming)面向切面编程的概念比较抽象,主要涉及下面这些术语:

  • Aspect(切面):切入一个或多个类的模块
  • Join point(连接点):程序执行的节点,例如执行方法或处理异常
  • Advice(通知):切面在连接点执行的动作,例如前置通知
  • Pointcut(切点):用于匹配连接点,一般通过表达式匹配
  • Target object(目标对象):被切入的对象,可以被一个或多个切面切入

一个目标类可以被多个切面切入,多个切面也可以切入一个目标类。

切面实现的本质是一个或多个基于连接点的拦截器。

AOP的运行

AOP提供了一种分离关注点的新维度,AOP会将这些关注点模块成称为“切面”的单独单元,这些切面可以独立开发、测试和重用。然后,将它们在需要的地点“编织”到主代码库中,确保核心逻辑保持不变且连贯。这种编织可以在不同的时间发生:

  • 编译时:编译应用程序时会编织各个切面。
  • 加载时:加载应用程序类时会编织各个切面。
  • 运行时:各个切面是在应用程序执行期间编织的。

AOP的好处

  • OOP非常适合使用类和对象对现实世界的对象和行为进行建模。但是,当涉及到跨模块间的的功能,OOP就显得不够用了。例如:如果你想在OOP结构中实现记录日志,你可能会在多个类中添加日志记录代码,这就显得非常冗余,随着时间的推移,这些重复的代码会扰乱主要逻辑,导致阅读、修改、调试变得非常困难。
  • 除了模块化之外,AOP还提供了高度的灵活性。由于切面与主要业务逻辑分离,因此对它们的更改不会影响核心代码。例如,如果更改日志记录的实现方式(也许切换到不同的日志库),则可以修改日志记录切面,而无需修改代码的任何其他部分。这种架构极大地简化了维护、减少了错误并提高了代码清晰度。

Spring AOP VS Full AspectJ

  • 值得注意的是,虽然 Spring AOP 涵盖了许多常见用例,但它并没有提供 AspectJ 等成熟 AOP 框架提供的所有功能。 Spring AOP 专注于通过代理进行运行时编织,而 AspectJ 可以在编译时或加载时编织切面,提供更广泛的连接点(如字段访问)。
  • AspectJ 是一个独立于 Spring 的,功能强大的 AOP 框架。它通过编译时植入(CTW, Compile-Time Weaving)或者运行时植入(LTW, Load-Time Weaving)来实现切面逻辑的织入。与 Spring AOP 相比,AspectJ 提供了更多的切面功能和更高的性能。Spring AOP 和 AspectJ 可以结合使用,利用 AspectJ 的强大功能和 Spring AOP 的简便配置。
  • 使用 AspectJ,需要在 Java 代码中创建切面类,并使用 @Aspect、@Pointcut、@Before、@After、@Around 等注解来定义切面和切点。编译时需要使用 AspectJ 编译器(ajc)编译代码,或者在运行时使用 Load-Time Weaving 实现切面逻辑的植入。

AOP原理

  • Spring AOP 的核心 Spring AOP 机制的核心是代理。当您定义一个切面来应用于应用程序的某些部分时,Spring 会创建advice对象的代理(子类或接口实现)。该代理拦截调用并将它们委托给原始对象,这种动态代理方法可确保不存在字节码操作,从而使过程透明且不易出错。Spring AOP 底层是基于动态代理实现的,对实现接口的类进行代理,默认使用 JDK 动态代理,对没实现接口的类,使用 CGLIB 动态代理。

JDK 动态代理通过实现接口生成代理类,使用拦截器加反射机制生成。

CGLIB 动态代理通过继承生成代理子类,使用字节码技术生成。通过子类对父类的方法进行重写来实现代理,因此,对 final 修饰的方法不能代理。

动态代理

JDK提供了invocationHandler接口和Proxy类,借助这两个工具可以达到我们想要的效果。 如果想更深入的的了解动态原理的实现,可以参照 Java 动态代理作用是什么? - 知乎

例子

若依的操作日志部分,注解此类 @Aspect ,简单粗暴,然后重写几个方法就可以

@Aspect
@Component
public class LogAspect
{

看几个方法,主要是 操作日志进行处理 SysOperLog 这是操作记录表,继承了BaseEntity,持久化到数据库里

  1. 使用@Before在切入点开始处切入内容
  2. 使用@AfterReturning在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
  3. 使用@AfterThrowing用来处理当切入内容部分抛出异常之后的处理逻辑

@Before(value = "@annotation(controllerLog)")
public void boBefore(JoinPoint joinPoint, Log controllerLog)
{TIME_THREADLOCAL.set(System.currentTimeMillis());
}/*** 处理完请求后执行** @param joinPoint 切点*/
@AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult)
{handleLog(joinPoint, controllerLog, null, jsonResult);
}/*** 拦截异常操作* * @param joinPoint 切点* @param e 异常*/
@AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e)
{handleLog(joinPoint, controllerLog, e, null);
}

可以推测,在有注解@Log 的Controller(可以随便找几个,完成测试) 的方法里面,在其前面, 在执行完成以后,或者发生异常的时候,我们都在这个方法上做了日志记录,很容易理解 切面的好处,以及是如何使用的。

总结

面向切面编程(AOP)是软件开发领域的游戏规则改变者。 @Aspect 和 @Pointcut 注解等工具,实现 AOP 变得更加简化,使开发人员能够专注于应用程序的核心逻辑,同时单独管理横切点。如果使用得当,这些注解可以带来更清晰、更易于维护和更高效的代码结构。

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

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

相关文章

CSDN,你的服务器挂了

浏览器访问一些文章,访问不到:https://blog.csdn.net/qq_40389276/article/details/99709890

未来编程语言什么样?编译解释兼容方为王

○、编程语言的未来? 随着科技的飞速发展,编程语言在计算机领域中扮演着至关重要的角色。它们是软件开发的核心,为程序员提供了与机器沟通的桥梁。那么,在技术不断进步的未来,编程语言的走向又将如何呢? …

基于人类反馈的强化学习(RLHF)

1. 监督微调(SFT):为了训练语言模型(LM)掌握基本的任务执行技能,首先需要构建一个监督数据集。这个数据集包含了指令性的输入提示和期望的输出结果,通过这些数据对LM进行精细调整。为了保证任务…

C#中的Attribute详解(上)

C#中的Attribute详解(上) 一、Attribute是什么二、Attribute的作用三、Attribute与注释的区别四、系统Attribute范例1、如果不使用Attribute,为了区分这四类静态方法,我们只能通过注释来说明,但这样做会给系统带来很多…

突破PHP disable_functions方法

1. 利用 LD_PRELOAD 环境变量 知识扫盲 LD_PRELOAD:是Linux系统的一个环境变量,它指定的*.so文件会在程序本身的*.so文件之前被加载。putenv():PHP函数,可以设置环境变量mail(),error_log():PHP函数&…

Python面向对象高级与Python的异常、模块以及包管理

Python面向对象高级与Python的异常、模块以及包管理 一、Python中的继承 1、什么是继承 我们接下来来聊聊Python代码中的“继承”:类是用来描述现实世界中同一组事务的共有特性的抽象模型,但是类也有上下级和范围之分,比如:生物 => 动物 => 哺乳动物 => 灵长型…

模式识别与机器学习-半监督学习

模式识别与机器学习-半监督学习 半监督学习半监督学习的三个假设半监督学习算法自学习算法自学习的步骤:自学习的优缺点:优点:缺点: 协同训练多视角学习生成模型半监督SVM 谨以此博客作为复习期间的记录 半监督学习 半监督学习&…

浅谈安科瑞智能照明系统在马来西亚国家石油公司项目的应用

摘要:随着社会经济的发展及网络技术、通信技术的提高,人们对照明设计提出了新的要求,它不仅要控制照明光源的发光时间、 亮度,而且与其它系统来配合不同的应用场合做出相应的灯光场景。本文介绍了马亚西亚石油公司智能照明项目的应…

大数据前馈神经网络解密:深入理解人工智能的基石

文章目录 大数据前馈神经网络解密:深入理解人工智能的基石一、前馈神经网络概述什么是前馈神经网络前馈神经网络的工作原理应用场景及优缺点 二、前馈神经网络的基本结构输入层、隐藏层和输出层激活函数的选择与作用网络权重和偏置 三、前馈神经网络的训练方法损失函…

蓝牙物联网智能安防系统设计方案

1概述 安防系统(安全防护)的作用是预防损失,是人们保障人身和财产安全最重要的工具之一。近年来,伴随经济的飞速发展和城市人口的急剧增加,盗窃、入室抢劫等事件的增多给人们的安定生活带来了很大的影响,同时,交通的快…

three.js绘制网波浪

无图不欢&#xff0c;先上图 使用方法&#xff08;以vue3为例&#xff09; <template><div class"net" ref"net"></div> </template><script setup> import { ref, onMounted } from vue import NetAnimation from /utils…

新能源汽车冷却系统的水道管口类型有哪些?格雷希尔针对这些管口密封的快速接头有哪些?

对于新能源汽车&#xff0c;不仅电池&#xff0c;还有电机、电控、充电单元部件&#xff0c;都需要处于适宜的工作温度&#xff0c;才能维持整车的正常运行。而这些部件在运行过程中会产生大量的热量&#xff0c;如果不及时散热会对汽车的性能、寿命产生影响&#xff0c;甚至可…

兔子目标检测数据集VOC格式3900张

兔子是一类可爱的哺乳动物&#xff0c;拥有圆润的脸庞和长长的耳朵&#xff0c;身体轻盈柔软。它们通常是以温和和友善的形象出现在人们的视野中&#xff0c;因此常常成为童话故事和卡通形象中的角色。 兔子是草食性动物&#xff0c;主要以各种草本植物为食&#xff0c;包括草…

深算院与新数科技达成战略合作,共筑国产数据库新生态

近日&#xff0c;深圳计算科学研究院&#xff08;以下简称“深算院”&#xff09;与北京新数科技有限公司&#xff08;以下简称“新数科技”&#xff09;达成战略合作。双方将融合发挥资源优势与技术优势&#xff0c;基于深算院自主研发设计的崖山数据库系统YashanDB&#xff0…

VD6283TX环境光传感器(2)----移植闪烁频率代码

VD6283TX环境光传感器----2.移植闪烁频率代码 闪烁定义视频教学样品申请源码下载参考代码硬件准备开发板设置生成STM32CUBEMX串口配置IIC配置X-CUBE-ALSADC使用定时器触发采样KEIL配置FFT代码配置app_x-cube-als.c需要添加函数演示结果 闪烁定义 光学闪烁是指人造光源产生的光…

conda环境下Could not build wheels for dlib解决方法

1 问题描述 在安装模型运行的conda环境时&#xff0c;出现如下问题&#xff1a; Building wheels for collected packages: basicsr, face-alignment, dlib, ffmpy, filterpy, futureBuilding wheel for basicsr (setup.py) ... doneCreated wheel for basicsr: filenamebasi…

【小程序】如何获取特定页面的小程序码

一、进入到小程序管理后台&#xff0c;进入后点击上方的“工具”》“生成小程序码” 小程序管理后台 二、进入开发者工具&#xff0c;打开对应的小程序项目&#xff0c;复制底部小程序特定页面的路径 三、粘贴到对应位置的文本框&#xff0c;点击确定即可

JMeter逻辑控制器之While控制器

JMeter逻辑控制器之While控制器 1. 背景2.目的3. 介绍4.While示例4.1 添加While控制器4.2 While控制器面板4.3 While控制器添加请求4.3 While控制器应用场景 1. 背景 存在一些使用场景&#xff0c;比如&#xff1a;某个请求必须等待上一个请求正确响应后才能开始执行。或者&…

C语言——指针题目“指针探测器“

如果你觉得你指针学的自我感觉良好&#xff0c;甚至已经到达了炉火纯青的地步&#xff0c;不妨来试试这道题目&#xff1f; #include<stdio.h> int main() {char* c[] { "ENTER","NEW","POINT","FIRST" };char** cp[] { c 3…

docker 安装可视化工具 Protainer 以及 汉化

一、创建保存数据的卷 安装网址&#xff1a;Install Portainer BE with Docker on Linux - Portainer Documentation docker pull portainer/portainer二、根据portainer镜像创建容器 docker run -d -p 8000:8000 -p 9000:9000\ --name portainer --restartalways \ -v /var/r…