案例分析的基本流程

核心提示一、AOP简介1.1 什么是AOPAOP面向切面编程,一种编程范式,指导开发者如何组织程序结构。OOP面向对象编程我们都知道OOP是一种编程思想,那么AOP也是一种编程思想,编程思想主要的内容就是指导程序员该如何编写程序,所以它们两个是不同

一、AOP介绍

1.1什么是AOP?

AOP(面向方面编程)是一种编程范式,指导开发人员如何组织程序结构。

OOP面向对象编程

我们都知道OOP是一种编程思想,所以AOP也是一种编程思想。编程思想的主要内容是指导程序员如何编写程序,所以是两种不同的编程范式。

1.2 AOP效应

功能:在不打乱原有设计的前提下,增强其功能。

1.3 AOP的核心概念

为了更好地理解AOP的相关概念,请观察下面的类

守则的内容相信大家都能理解。对于save方法,计算10,000次执行的消耗需要时间。

当从App类的容器中获取bookDao对象时,分别执行其save、delete、update和select方法后,会得到如下打印结果:

这个时候,我们应该有一些疑问。

对于计算一万次执行所消耗的时间,只有save方法有。为什么删除和更新方法也有?

和删除更新方法,那么为什么不选择方法呢?

其实这个用的是Spring的AOP。在不打乱原设计的前提下,想给谁加功能就给谁加。这是春天的想法:

非侵入性/非侵入性

说了这么多,春天是怎么实现的?

有人强调,Spring的AOP是在不做任何修改的情况下增强一个类的方法。对于上面的BookServiceImpl,有保存、更新、删除和选择方法,我们将这些方法命名为连接点。

BookServiceImpl的四个方法中,update和delete不计算10000次执行的消耗时间,但是它们在运行时已经有这个功能了,也就是说,update和delete方法都得到了增强,所以我们给需要增强的方法起个名字作为突破点。

在执行BookServiceImpl的update和delete方法时,增加了一个计算万次执行耗时的函数。这个函数被提取成一个方法,换句话说就是存储常用函数的方法,我们把它命名为Notice。

通知是要增强的内容,会有多个切入点,哪些方法需要增强,也会有多个切入点。那么,如果哪个切入点需要添加哪个通知,需要事先把两者之间的关系描述清楚。然后,我们给通知和切入点的关系描述起一个名字,叫做切入。

通知是一个方法,不能独立存在,需要写在一个类里。我们还将这个类命名为通知类。

至此,AOP中的核心概念已经介绍完毕。总而言之:

连接点:程序执行过程中的任何位置,具有执行方法、抛出异常、设置变量等粒度。

这个概念很大。在SpringAOP中,一般理解为方法的执行。

切入点:匹配连接点的公式

一个具体的方法:比如Dao包下的BookDao接口中的不可见参数就是save方法,没有返回值。

匹配方法:所有保存方法,所有入门方法,所有以Dao结尾的接口中的任意方法,以及所有带一个参数的方法。

在SpringAOP中,一个切入点可以描述一个特定的方法,也可以匹配多个方法。

连接点的范围比切入点大,作为切入点的方法也一定是连接点,但是作为连接点的方法不一定要增强,所以不一定是切入点。

通知:在切入点执行的操作,也就是公共函数。

在SpringAOP中,函数最终以方法的形式呈现。

类别:定义通知的类别。

小节:描述通知和切入点之间的对应关系。

二、AOP介绍案例

2.1需求分析

案例:衡量接口执行效率,但这个有点复杂,我们就简化一下。

Simplify:在执行方法之前输出当前系统时间。

2.2思路分析

需求明确后,如何实现,有哪些步骤?

1.导入坐标

2.制作连接点

3.制作常用函数。

4.定义入口点

5.绑定切入点和通知关系

2.3环境准备

创建一个Maven项目

向pom.xml添加Spring依赖项

org.springframework spring-context 5.2.10.RELEASE

添加BookDao和BookDaoImpl类

为Spring创建一个配置类

@Configuration@ComponentScan public class SpringConfig { }

写App跑步类

最终的项目结构如下:

描述:

目前,在打印save方法时,运行时可以看到系统时间,因为该方法有打印系统时间。

对于update方法,没有这样的函数。

我们想在不改变更新方法的情况下,使用SpringAOP打印系统时间。

2.4 AOP实现步骤

步骤1:添加依赖关系

pom.xml

aspectj aspectjweaver 1.9.4

因为spring-aop已经导入到spring-context中,所以没有必要单独导入spring-aop。

导入AspectJ的jar包。AspectJ是AOP思想的具体实现。Spring有自己的AOP实现,但是比AspectJ麻烦,所以我们直接用Spring集成ApsectJ进行AOP开发。

步骤2:定义接口和实现类。

在准备环境的时候,BookDaoImpl已经准备好了,没有任何修改。

步骤3:定义通知类和通知。

通知是提取常用函数形成的方法,是指打印当前系统时间。

类名和方法名不是必需的,可以是任意的。

步骤4:定义切入点

BookDaoImpl中有两种方法,即保存和更新。我们要增强的是更新方法。怎么定义?

描述:

切入点的定义依赖于一个没有实际意义的方法,即方法体中没有参数,没有返回值,没有实际逻辑。

执行和后面写的内容,后面会介绍,这里只是介绍一下用法。

第五步:制作切面。

一节用来描述通知和切入点之间的关系以及如何绑定这种关系。

绑定切入点和通知的关系,指定通知添加到原始连接点的具体执行位置。

解释:@Before翻译为Before,意思是通知会在切入点方法执行之前执行。在那之前还有另外四种类型,后面会介绍。

步骤6:将通知类分配给容器,并将其标识为节类。

第七步:打开注释格式AOP功能

步骤8:运行程序

看到update方法执行前打印了系统时间戳,说明原来的方法已经增强,AOP编程成功。

1: @ EnableAspectJautoProxy

知识点二:@ aspect

知识点:@切入点

知识点:@之前

三。AOP工作流

AOP的入门案例已经完成,我们还要分析刚才案例的实现过程,主要包括两个知识点:AOP工作流和AOP的核心概念。

3.1 AOP工作流程

由于AOP是由Spring容器管理的bean增强的,所以整个工作过程需要从Spring加载bean开始:

1:弹簧容器启动。

容器启动时需要加载Bean。需要加载哪些类?

需要增强的类,比如BookServiceImpl

类,如:MyAdvice

请注意,bean对象尚未成功创建。

2:读取所有切面配置中的切入点。

在上面的例子中配置了两个切入点,但是第一个ptx没有使用,所以不会被读取。

3:初始化bean

确定对应于bean的类中的方法是否匹配任何切入点。

注意步骤1当容器启动时,bean对象还没有成功创建。

匹配要实例化的bean对象的类中的方法和切入点。

匹配成功表明它需要被增强。

哪个类增强了,这个类对应的对象就叫目标对象。

因为要增强目标对象的功能,采用的技术是动态代理,所以会为它创建一个代理对象。

最后,将运行代理对象的方法,其中将增强原始方法。

匹配失败意味着不需要增强,直接调用原对象的方法即可。

匹配失败,创建原始对象,如UserDao。

匹配成功,创建原对象的代理对象,如:BookDao。

4:获取bean执行方法。

当获得的bean是原始对象时,调用方法并执行它以完成操作。

当获取的bean是代理对象时,按照代理对象的运行方式运行原方法和增强内容,完成操作。

验证容器是代理对象。

要验证IOC容器中创建的对象是否与我们刚刚提到的结论一致,先整理一下结论:

如果目标对象中的方法将被增强,则目标对象的代理对象将被存储在容器中。

如果目标对象中的方法没有得到增强,目标对象本身将被存储在容器中。

验证思路

1.要执行的方法没有包含在定义的切入点中,也就是没有增强,打印当前类的getClass方法。

2.对于要执行的方法,定义的切入点包含,也就是当前类的getClass方法要增强并打印出来。

3.观察两次打印的结果。

第一步:修改App类,获取类的类型。

第2步:修改MyAdvice类,不进行增强。

因为定义的切入点修改为update1,所以BookDao中的update方法在执行时不会得到增强。

所以容器中的对象应该是目标对象本身。

第三步:运行程序。

步骤4:修改MyAdvice类以增强

因为定义的切入点被修改为update,所以BookDao中的update方法在执行时会得到增强。

所以容器中的对象应该是目标对象的代理对象。

第五步:运行程序。

至此,我们已经验证了刚才的结论。大家需要注意的是:

不能直接打印对象。从上面两个结果可以看出,对象的直接打印取对象的toString方法,无论代理对象打印与否,结果都是一样的,因为toString方法是内部重写的。

3.2 AOP的核心概念

在上述AOP的工作流程中,我们提到了两个核心概念,即:

对象:原函数去掉了常用函数对应的类生成的对象,不能直接完成最后的工作。

代理:目标对象不能直接完成工作,需要原对象的代理对象回填。

以上两个概念比较抽象。简单来说,

对象是要增强的类[如BookServiceImpl类]对应的对象,也叫原始对象。不能说不能跑,只是在跑的过程中缺少了要增强的内容。

SpringAOP在不改变原设计的情况下进行了增强,其底层采用代理模式实现。因此,要增强原始对象,需要为原始对象创建一个代理对象。proxy对象中的方法添加通知[例如MyAdvice中的方法]来实现增强,这就是我们所说的代理。

资料来源:file/tupian/20220910/16412308.html

 
友情链接
鄂ICP备19019357号-22