【Spring篇】spring核心——AOP面向切面编程

目录

想要彻底理解AOP,我觉得你的先要了解框架的模块化思想,为此先记录框架在讲AOP

什么是java框架?为什么要出现框架?

我总结以下七点来讲述和帮助理解java框架思想 

什么是AOP?

如何理解上面这句话呢?

最重要的来了,什么是面向切面编程?

我们现在将横向的关注点剥离成了一个一个的切面,呢我们如何用代码把切面织入进去呢?

呢么现在就有了新的问题:什么是AspectJ框架?他在AOP编程中起到了什么作用?

知道了概念之后我们开始使用

Spring AOP的实现原理

最后概念化AOP


想要彻底理解AOP,我觉得你的先要了解框架的模块化思想,为此先记录框架在讲AOP

什么是java框架?为什么要出现框架?

在我开始接触java框架知识后,我发现所谓的java框架就是把原本的一个整体分成了一小块一小块的部分,有种模块化思想,就是将分工变得更加明确,专业的人负责专门的事,让程序员更加专注于业务本身,将什么事务操作、日志操作抽取出去,模块化成一个小整体去专门负责做,然后将这个小整体做好后,像堆积木一样堆到事务该出现的位置,然后让一块一块的小积木堆成一个搭积;

我总结以下七点来讲述和帮助理解java框架思想 

  1. 模块化思想: 框架通常采用模块化设计,将系统拆分成独立的功能模块。每个模块专注于特定的功能或关注点,如数据库访问、事务管理、日志记录、安全性等。这种模块化思想使得系统更易于理解、扩展和维护。

  2. 分工明确: 各个模块由专业的开发者或团队负责,这样可以充分发挥每个人的专业技能。例如,数据库模块由专门的数据库开发者负责,日志模块由专门的日志开发者负责。这种分工使得开发过程更加高效,同时降低了系统的复杂性。

  3. 抽象和封装: 框架通过抽象和封装隐藏了底层的复杂性,提供了高层次的接口供开发者使用。这样,开发者在使用框架时不需要关心底层的实现细节,只需关注业务逻辑的实现。这种抽象和封装有助于提高代码的可读性和可维护性。

  4. 面向切面编程(AOP): AOP 是一种重要的框架设计思想,它允许将横切关注点(cross-cutting concerns)从主要业务逻辑中分离出来。例如,事务管理、安全性、日志记录等关注点可以被模块化成切面,然后通过AOP织入到业务逻辑中。这使得系统的关注点更加清晰,同时避免了代码重复。

  5. 依赖注入(DI): 框架通常使用依赖注入来管理组件之间的依赖关系。这样,开发者不需要手动创建和管理对象之间的关系,而是由框架负责。DI提高了代码的灵活性和可测试性。

  6. 约定优于配置(Convention over Configuration): 框架倡导使用一些默认约定,减少配置的复杂性。通过约定,开发者只需要配置那些与默认约定不一致的部分,减少了样板代码的编写,提高了开发效率。

  7. 开放封闭原则: 框架遵循开放封闭原则,允许系统扩展而不需要修改已有的代码。新的功能通过扩展现有的模块或添加新的模块来实现,而不是修改已有的代码。这种原则有助于保持系统的稳定性和可维护性。

 框架就是为了让一个复杂代码的逻辑更加清晰,分工更加明确;

什么是AOP?

        Spring有两个极其重要的核心概念,一个是IOC/DI,另一个就是AOP呢么什么是AOP呢?刚刚已经总结过了,AOP 是一种重要的框架设计思想,它允许将横切关注点(cross-cutting concerns)从主要业务逻辑中分离出来。例如,事务管理、安全性、日志记录等关注点可以被模块化成切面,然后通过AOP织入到业务逻辑中(就好比搭积木)。这使得系统的关注点更加清晰,还增加了代码的复用性。

如何理解上面这句话呢?

        假设将我们编写的业务代码看成一个搭积木的过程,我们将交叉业务看成一个个小积木,当我们做完核心业务代码之后,然后将做好的小积木像搭积木一样,加入已经做好的小积木块,这样就避免了我们程序员在编写主要业务逻辑时,还要考虑数据库事务啊,访问数据库啊等,其他和业务无关的逻辑,让我们程序员负责写订单生成的就只负责写订单生成,负责写数据库访问的就只负责写数据库访问,使的分工明确,结构清晰,最后拼在一起即可构成高楼大厦;

        这里的积木与积木之间是否能够拼在一起就能正常运行就涉及到解耦合思想了;

看上面这张图,我们将业务代码看成纵向的一个过程,将和业务主要代码无关的代码,如事务管理、安全性、日志记录等关注点可以被模块化成小积木块,等需要这些的时候,像刀一样横向的插入进去,然而能够把一个整体抽象成模块化的思想就是AOP的主要思想;


最重要的来了,什么是面向切面编程?

        我们把事务管理、安全性、日志记录等和主从业务无关的关注点看成一个一个的切面,将他们从主要业务逻辑中分离出来。然后在需要用到他们的地方再将他们织入进去,当然这需要完全的解耦合;


我们现在将横向的关注点剥离成了一个一个的切面,呢我们如何用代码把切面织入进去呢?

呢我们就要说到spring对AOP的实现技术,AspectJ框架,实际开发中,都是Spring+AspectJ来实现AOP。

常用的Spring对AOP的实现包括以下2种方式:

  • 第一种方式:Spring框架结合AspectJ框架实现的AOP,基于注解方式。
  • 第二种方式:Spring框架结合AspectJ框架实现的AOP,基于XML方式。

依赖如下:

<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>6.0.0-M2</version>
</dependency>

呢么现在就有了新的问题:什么是AspectJ框架?他在AOP编程中起到了什么作用?

AspectJ是一个基于Java的面向切面编程(AOP)框架,它提供了一种强大的方式来实现横切关注点的模块化。我们刚刚不是已经将关注点剥离成了切面吗?呢JVM怎么知道你就是切面呢他怎么知道这个切面要放到哪里呢,还有他怎么就知道代码执行到一半还要先执行切面呢?AspectJ的作用就出来了;

在AOP中,AspectJ主要起到以下作用:

  1. 切面定义: AspectJ允许开发者定义切面,切面是横切关注点的模块化单元。切面通常包含一组通知(advice)以及切点(pointcut)的定义。

  2. 通知(Advice): 通知是切面中的代码块,它定义了在目标方法的哪个时机执行。AspectJ支持五种类型的通知:前置通知(Before advice)、后置通知(After advice)、返回通知(After-returning advice)、异常通知(After-throwing advice)和环绕通知(Around advice)。

  3. 切点(Pointcut): 切点定义了在目标类中的哪些位置执行通知。AspectJ允许开发者使用表达式来定义切点,从而选择性地将通知应用到目标类的特定方法或代码块

  4. 连接点(Join point): 连接点是在程序执行过程中可以插入切面的点。AspectJ将切点看作连接点,并在连接点上执行相应的通知。

  5. 织入(Weaving): 织入是将切面与目标类或对象关联的过程。AspectJ使用编译时织入、类装载时织入和运行时织入等方式来将切面织入到目标代码中。

  6. 增强(Introduction): AspectJ允许通过引入(Introduction)在不修改目标类代码的情况下为类添加新的方法或字段。这对于为已有的类添加新的行为非常有用。

  7. 类型匹配和织入控制: AspectJ提供了丰富的类型匹配和织入控制的功能,允许开发者精确地指定切面的应用范围。

总体而言,AspectJ通过定义切面、通知、切点等概念,使得开发者能够以一种更模块化和清晰的方式处理横切关注点。通过AspectJ,可以将与业务逻辑无关的关注点(如日志、事务、安全性等)独立出来,使得代码更易维护、扩展和理解


知道了概念之后我们开始使用

我们引入一个案例:一个订单生成业务,我们需要再订单生成方法执行前织入一个切面MyAspect ,添加一些增强代码:

// 目标类
@service
public class OrderService {// 目标方法public void generate(){System.out.println("订单已生成!");}
}

切面类:

// 切面类
@Aspect
@Component
public class MyAspect {// 切点表达式@Before("execution(* com.lypnode.spring.service.OrderService.*(..))")// 这就是需要增强的代码(通知)public void advice(){System.out.println("我是一个通知");}
}

 使用了AspectJ框架中的@Aspect这个注解之后,就表明这个类是个切面类,

spring.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><!--开启组件扫描--><context:component-scan base-package="com.lypnode.spring.service"/><!--开启自动代理--><aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>

<aop:aspectj-autoproxy proxy-target-class="true"/> 开启自动代理之后,凡事带有@Aspect注解的bean都会生成代理对象。

proxy-target-class="true" 表示采用cglib动态代理。

proxy-target-class="false" 表示采用jdk动态代理。默认值是false。即使写成false,当没有接口的时候,也会自动选择cglib生成代理类。

关于cglib动态代理和jdk动态代理下面我们会说:

 测试类:

public class AOPTest {@Testpublic void testAOP(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");OrderService orderService = applicationContext.getBean("orderService", OrderService.class);orderService.generate();}
}

运行结果: 

 

通过上面的总结和代码我么可以知道,AOP底层是调用了动态代理技术的,呢么就会生成代理类,可见上面的代码中,看似在调用orderService类,实则调用的是动态生成的代理类

 至于代理类生成看我另一篇文章:

【Spring篇】JDK动态代理-CSDN博客


Spring AOP的实现原理

Spring的AOP实现原理其实很简单,就是通过动态代理实现的。Spring AOP 采用了两种混合的实现方式:JDK 动态代理和 CGLib 动态代理。

JDK动态代理:Spring AOP的首选方法。 每当目标对象实现一个接口时,就会使用JDK动态代理。目标对象必须实现接口
CGLIB代理:如果目标对象没有实现接口,则可以使用CGLIB代理。

Spring默认使用JDK的动态代理实现AOP,类如果实现了接口,Spring就会使用这种方式实现动态代理。当然你也可以自己制定;

proxy-target-class="true" 表示采用cglib动态代理。

proxy-target-class="false" 表示采用jdk动态代理。默认值是false。即使写成false,当没有接口的时候,也会自动选择cglib生成代理类。

最后概念化AOP

AOP 是一种重要的框架设计思想,动态代理是其实现机制之一。在 AOP 中,可以通过动态代理将横切关注点与核心业务逻辑分离,使代码更易维护和理解。它允许将横切关注点(cross-cutting concerns)从主要业务逻辑中分离出来。例如,事务管理、安全性、日志记录等关注点可以被模块化成切面,然后通过AOP织入到业务逻辑中。这使得系统的关注点更加清晰,同时避免了代码重复。

AOP可以拦截指定的方法并且对方法进行增强,而且无需侵入到业务代码中,使业务与非业务处理逻辑分离,比如数据库访问、事务管理、日志记录、安全性等。这种模块化思想使得系统更易于理解、扩展和维护。

将系统拆分成独立的功能模块。每个模块专注于特定的功能或关注点,如数据库访问、事务管理、日志记录、安全性等。这种模块化思想使得系统更易于理解、扩展和维护。


这是我对AOP面向切面编程的初步理解,内容有点复杂,逻辑有点乱,后续还会修改文章;

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

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

相关文章

快速压缩:迅速减小PDF文件大小的步骤与技巧

虽然png图片格式是一种无损压缩格式&#xff0c;但是png图片的内存大小也是比较大的&#xff0c;而且兼容性上也没有jpg图片好&#xff0c;许多平台推荐的也都是jpg格式&#xff0c;所以当我们需要把png转jpg格式的时候&#xff0c;就需要用到图片格式转换器&#xff0c;今天推…

Pure-Pursuit 跟踪五次多项式轨迹

Pure-Pursuit 跟踪五次多项式轨迹 考虑双移线轨迹 X 轴方向位移较大&#xff0c;机械楼停车场长度无法满足 100 ~ 120 m&#xff0c;因此采用五次多项式进行轨迹规划&#xff0c;在轨迹跟踪部分也能水一些内容 调整 double_lane.cpp 为 ref_lane.cpp&#xff0c;结合 FrenetP…

鸿蒙开发报错:agconnect sdk not initialized. please call initialize()【BUG已解决】

文章目录 项目场景:问题描述原因分析:解决方案:总结:项目场景: 鸿蒙开发报错: agconnect sdk not initialized. please call initialize() 问题描述 报错内容为: 10-25 11:41:01.152 6076-16676 E A0c0d0/JSApp: app Log: 数据查询失败: {“code”:1100001,“messag…

使用VC++设计程序对一幅256级灰度图像进行全局固定阈值分割、自适应阈值分割

图像分割–全局固定阈值分割、自适应阈值分割 获取源工程可访问gitee可在此工程的基础上进行学习。 该工程的其他文章&#xff1a; 01- 一元熵值、二维熵值 02- 图像平移变换&#xff0c;图像缩放、图像裁剪、图像对角线镜像以及图像的旋转 03-邻域平均平滑算法、中值滤波算法、…

定长子网划分和变长子网划分问题_二叉树解法_通俗易懂_配考研真题

引入:定长子网划分和变长子网划分的基本概念 定长子网划分和变长子网划分的基本概念 目前常用的子网划分&#xff0c;是基于CIDR的子网划分&#xff0c;也就是将给定的CIDR地址块划分为若干个较小的CIDR地址块。 定长子网划分: 使用同一个子网掩码来划分子网&#xff0c;因…

libmosquitto库的一个bug,任务消息id(mid)分配后不起作用

代码如图所示: 当订阅了所有主题后,每个主题的mid是他们的下标索引加100的数字,可是实际打印出来的值是: mid依然是1,2,这个参数在这里失效了,不知道是bug还是mqtt的什么机制?

武汉数字孪生赋能工业制造,加速推进制造业数字化转型

随着数字孪生技术的不断推进&#xff0c;互联网、物联网、智能传感技术开始应用到数控机床的远程服务&#xff0c;状态监控&#xff0c;故障诊断&#xff0c;维护管理等方面。武汉数字孪生是在虚拟空间中创建物理对象的高保真虚拟模型&#xff0c;以模拟其在现实世界中的行为提…

2023年03月 Scratch(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 计算“2+4+8+……+128”,用变量n表示每项,根据变化规律,变量n的赋值用下列哪个最合适?( ) A: B: C: D: 答案:D

叠加原理(superposition principle)

叠加原理&#xff08;superposition principle&#xff09;指对线性系统而言&#xff0c;两个或多个输入产生的输出&#xff0c;等于这几个输入单独引起的输出的和&#xff0c;即输入的叠加等于各输入单独引起的输出的叠加。 例如&#xff0c;如果输入产生的输出是&#xff0c;…

「C++」入门

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;C启航 &#x1f387;欢迎点赞收藏加关注哦&#xff01; 文章目录 &#x1f349;前言&#x1f349;命名空间&#x1f34c;访问命名空间中的元素&#x1f34c;同名命名空间&#x1f34c;展开&…

2018年1月22日 Go生态洞察:Hello, 中国!

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

C语言之指针知识点总结

C语言之指针知识点总结 文章目录 C语言之指针知识点总结1. 初识指针1.1 取地址操作符 &1.2 指针变量1.3 解引用操作符 *1.4 指针变量1.4.1 大小1.4.2 指针类型的意义 1.5 void*指针1.6 const关键字1.61 const修饰变量1.6.2 const修饰指针变量 1.7 指针的运算1.7.1 指针-整数…

pyhon数据分析A股股票策略实际买卖总结(每月末更新数据)

简介 本篇文章主要记录python数据分析a股股票选股后实际买卖的记录。 选股策略 低位寻股&#xff0c;筛选出低位股价股票已经做过调整的股票&#xff0c;做短线交易&#xff08;不超过7天&#xff09;&#xff0c;不贪&#xff0c;小赚即走。分三个时段&#xff0c;开盘三十…

SAS9.2软件“OLE:对象的类没有在注册数据库中注册“问题的解决. 2023-11-25

操作系统测试平台: Win7 sp1 32bit (6.1.7601.26321 (Win7 RTM)) ; Win 11 64bit(具体版本不详) 其它win平台理论上也可以,可自行测试 1.安装依赖库(必要步骤) 下载地址: Microsoft Visual C 2005 Redistributable 下载 Microsoft Visual C 2008 Redistributable 官方vc库总…

buuctf web [极客大挑战 2019]PHP

提示有备份,dirsearch扫描网站备份 GitHub - maurosoria/dirsearch: Web path scanner下载.zip格式文件 解压到python目录下 在上图位置cmd打开窗口 输入python setup.py install安装dirsearch 安装好后输入命令使用dirsearch python dirsearch.py -u http://44296191-973d-…

第一百八十回 介绍两种阴影效果

文章目录 1. 概念介绍2. 实现方法3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"自定义SlideImageSwitch组件"相关的内容&#xff0c;本章回中将介绍两种阴影效果.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在…

【深入剖析K8s】容器技术基础(一):从进程开始说起

容器其实是一种特殊的进程而已。 可执行镜像 为了能够让这些代码正常运行’我们往往还要给它提供数据’比如我们这个加法程序所需要的输人文件这些数据加上代码本身的二进制文件放在磁盘上’就是我们平常所说的一个程序,也叫代码的可执行镜像&#xff08;executablejmage&…

用xlwings新建一个excel并同时生成多个sheet

新建一个excel并同时生成多个sheet&#xff0c;要实现如下效果&#xff1a; 一般要使用数据透视表来快速实现。 今天记录用xlwings新建一个excel并同时生成多个sheet。 import xlwings as xw # 打开excel,参数visible表示处理过程是否可视,add_book表示是否打开新的Excel程序…

CSDN助手:一键下载CSDN博客:高效保存,随时阅读

文章目录 &#x1f4d6; 介绍 &#x1f4d6;&#x1f3e1; 环境 &#x1f3e1;&#x1f4d2; 使用方法 &#x1f4d2;⚓️ 相关链接 ⚓️ &#x1f4d6; 介绍 &#x1f4d6; 这是我自己无聊的时候写的一个应用&#xff0c;以前UI有点丑&#xff0c;这次重写了一下UI 功能如下 …

vue+elementui如何实现在表格中点击按钮预览图片?

效果图如上&#xff1a; 使用el-image-viewer 重点 &#xff1a; 引入 import ElImageViewer from "element-ui/packages/image/src/image-viewer"; <template><div class"preview-table"><el-table border :data"tableData" …