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

news2024/11/26 21:43:52

我们进入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://www.coloradmin.cn/o/1342071.html

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

相关文章

【Vue2 + ElementUI】el-table中校验表单

一. 案例 校验金额 阐述&#xff1a;校验输入的金额是否正确。如下所示&#xff0c;点击【编辑图标】会变为input输入框当&#xff0c;输入金额。当输入框失去焦点时&#xff0c;若正确则调用接口更新金额且变为不可输入状态&#xff0c;否则返回不合法金额提示 <templat…

Java小案例-一招弄懂线程池

前言 今天跟大家聊一聊无论是在工作中常用还是在面试中常问的线程池&#xff0c;通过画图的方式来彻底弄懂线程池的工作原理&#xff0c;以及在实际项目中该如何自定义适合业务的线程池。 一、什么是线程池 线程池其实是一种池化的技术的实现&#xff0c;池化技术的核心思想…

渗透测试(Lab4.2)

配置WebDeveloper的时候遇到一个错误 导入失败&#xff0c;因为 E:…ovf 未通过 OVF 规范一致性或虚拟硬件合规性检查。 请单击“重试”放松 OVF 规范与虚拟硬件合规性检查&#xff0c;并重新尝试导入&#xff1b; 或单击“取消”以取消导入。如果重新尝试导入&#xff0c;可能…

请问仿写arkts摇杆功能,为什么我的代码,TouchType.Up 时候摇杆动画不能还原呢?请求大佬指点一下

仿照黑马的arkts 写个摇杆功能&#xff0c;但是为什么我的代码&#xff0c;TouchType.Up 时候摇杆动画不能还原&#xff0c; 请求大佬指点一下 import router from ohos.router import curves from ohos.curvesEntry Component struct ItemPage7 {// 小鱼坐标State fishX: nu…

Springboot实现登录注册

功能&#xff1a;1、实现用户的登录 2、实现用户的注册以及重名的判断 LoginControl&#xff1a; package com.example.demo.controls;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; imp…

2024 年政府和技术预测

新的一年即将来临&#xff0c;这意味着专家、技术专家和专栏作家应该尝试预测 2024 年政府和技术即将出现的一些最大趋势。今年可能使这些预测变得更加困难的是事实上&#xff0c;许多技术正在以惊人的速度向前发展。在某些情况下&#xff0c;过去需要多年才能慢慢发生的变化现…

乘势而上开新年!2024深圳深圳户外家具及休闲用品展览会三月开幕

中国户外家具市场在九十年代末开始崭露头角&#xff0c;随着国家经济的腾飞&#xff0c;尤其是房地产行业的迅猛发展&#xff0c;加上现代商业模式的建立和完善&#xff0c;产品和需求都以惊人的速度在发展。无论是国际知名品牌&#xff0c;还是国内的专业户外家具生产企业&…

java设计模式学习之【模板方法模式】

文章目录 引言模板方法模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用游戏设计示例代码地址 引言 设想你正在准备一顿晚餐&#xff0c;无论你想做意大利面、披萨还是沙拉&#xff0c;制作过程中都有一些共同的步骤&#xff1a;准备原料、加工食物、摆盘。…

你知道继电保护测试仪的价格是多少吗?

继电保护测试仪是电气设备检测中经常使用的检测仪器。它能准确、快速地检测到每个继电保护装置的一些潜在故障和问题&#xff0c;帮助电力检测工人锁定问题点&#xff0c;使继电保护装置能够正常工作&#xff0c;保护电力需求。继电保护测试仪贵吗&#xff1f;哪些因素影响价格…

Hive讲课笔记:内部表与外部表

文章目录 一、导言二、内部表1.1 什么是内部表1.1.1 内部表的定义1.1.2 内部表的关键特性 1.2 创建与操作内部表1.2.1 创建并查看数据库1.2.2 在park数据库里创建student表1.2.3 在student表插入一条记录1.2.4 通过HDFS WebUI查看数据库与表 三、外部表2.1 什么是外部表2.2 创建…

优思学院|做了3年QC感到前路茫茫,我应该如何规划职业路径?

网友提问&#xff1a; 做了3年QC感到前路茫茫我应该如何规划职业路径&#xff1f; 在当今这个快速发展和竞争激烈的时代&#xff0c;许多质量控制&#xff08;QC&#xff09;领域的专业人士&#xff0c;如你所述&#xff0c;可能会感到职业发展上的迷茫。 作为一名拥有三年QC经…

JavaWeb——JQuery

文章目录 JQuery 是什么?jQuery 的原理示意图JQuery 基本开发步骤jQuery 对象和 DOM 对象将dom对象转为JQuery对象jQuery 对象转成 DOM 对象jQuery 选择器基本选择器基础过滤选择器JQuery 是什么? 基本介绍 jQuery 是一个快速的,简洁的 javaScript 库,使用户能更方便地处理…

elasticsearch系列七:聚合查询

概述 今天咱们来看下es中的聚合查询&#xff0c;在es中聚合查询分为三大类bucket、metrics、pipeline&#xff0c;每一大类下又有十几种小类&#xff0c;咱们各举例集中&#xff0c;有兴许的同学可以参考官网&#xff1a;https://www.elastic.co/guide/en/elasticsearch/refere…

ClickHouse基础知识(五):ClickHouse的SQL 操作

基本上来说传统关系型数据库&#xff08;以 MySQL 为例&#xff09;的 SQL 语句&#xff0c;ClickHouse 基本都支持&#xff0c; 这里不会从头讲解 SQL 语法只介绍 ClickHouse 与标准 SQL&#xff08;MySQL&#xff09;不一致的地方。 1. Insert 基本与标准 SQL&#xff08;My…

【Vue2+3入门到实战】(13)插槽<slot>详细示例及自定义组件的创建与使用代码示例 详解

目录 一、学习目标1.插槽2.综合案例&#xff1a;商品列表 一、插槽-默认插槽1.作用2.需求3.问题4.插槽的基本语法5.代码示例6.总结 二、插槽-后备内容&#xff08;默认值&#xff09;1.问题2.插槽的后备内容3.语法4.效果5.代码示例 三、插槽-具名插槽1.需求2.具名插槽语法3.v-s…

BDD - Python Behave 配置文件 behave.ini

BDD - Python Behave 配置文件 behave.ini 引言behave.ini配置参数的类型配置项 behave.ini 应用feature 文件step 文件创建 behave.ini执行 Behave查看配置默认值 behave -v 引言 前面文章 《BDD - Python Behave Runner Script》就是为了每次执行 Behave 时不用手动敲一长串…

node 项目中 __dirname / __filename 是什么,为什么有时候不能用?

__dirname 是 Node.js 中的一个特殊变量&#xff0c;表示当前执行脚本所在的目录的绝对路径。 __filename 同理&#xff0c;是 Node.js 中的一个特殊变量&#xff0c;表示当前执行脚本的绝对路径&#xff0c;包括文件名。 在 Node.js 中&#xff0c;__dirname / __filename是…

C语言 linux文件操作(二)

文章目录 一、获取文件长度二、追加写入三、覆盖写入四、文件创建函数creat 一、获取文件长度 通过lseek函数&#xff0c;除了操作定位文件指针&#xff0c;还可以获取到文件大小&#xff0c;注意这里是文件大小&#xff0c;单位是字节。例如在file1文件中事先写入"你好世…

Vue - v-for 指令详解

1. 渲染列表 首先&#xff0c;让我们看看如何使用 v-for 渲染一个简单的列表。在 Vue.js 中&#xff0c;我们可以使用 v-for 来遍历数组&#xff0c;并根据数组中的每个元素渲染相应的内容。 <template><div><!-- 使用 v-for 渲染列表 --><ul><li…

计算机与人工智能:共创智能时代的新篇章

计算机与人工智能&#xff1a;共创智能时代的新篇章 在这个科技日新月异的时代&#xff0c;计算机与人工智能&#xff08;AI&#xff09;的结合正以前所未有的速度改变着世界。它们在各自的领域内飞速发展&#xff0c;而当这两者相遇时&#xff0c;它们产生了巨大的能量&#x…