AOP开发

简介: 本文介绍AOP切面编程思想开发

1、简介

1.1、AOP 相关概念

Spring 的 AOP 实现底层就是对上面的动态代理的代码进行了封装,封装后我们只需要对需要关注的部分进行代码编写,并通过配置的方式完成指定目标的方法增强。

在正式讲解 AOP 的操作之前,我们必须理解 AOP 的相关术语,常用的术语如下:

  1. Target(目标对象):代理的目标对象
  2. Proxy (代理):一个类被 AOP 织入增强后,就产生一个结果代理类
  3. Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点
  4. Pointcut(切入点):所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义
  5. Advice(通知/ 增强):所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知
  6. Aspect(切面):是切入点和通知(引介)的结合
  7. Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程。spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入

1.2、AOP 开发明确的事项

1. 需要编写的内容

编写核心业务代码(目标类的目标方法)

编写切面类,切面类中有通知(增强功能方法)

在配置文件中,配置织入关系,即将哪些通知与哪些连接点进行结合

2. AOP 技术实现的内容

Spring 框架监控切入点方法的执行。一旦监控到切入点方法被运行,使用代理机制,动态创建目标对象的

代理对象,根据通知类别,在代理对象的对应位置,将通知对应的功能织入,完成完整的代码逻辑运行。

3. AOP 底层使用哪种代理方式

在 spring 中,框架会根据目标类是否实现了接口来决定采用哪种动态代理的方式。

1.3、知识要点

  1. aop:面向切面编程
  2. aop底层实现:基于JDK的动态代理 和 基于Cglib的动态代理
  3. aop的重点概念:
  1. Pointcut(切入点):被增强的方法
  2. Advice(通知/ 增强):封装增强业务逻辑的方法
  3. Aspect(切面):切点+通知
  4. Weaving(织入):将切点与通知结合的过程
  1. 开发明确事项:
  1. 谁是切点(切点表达式配置)
  2. 谁是通知(切面类中的增强方法)
  3. 将切点和通知进行织入配置

2、两种方式

AOP(Aspect-Oriented Programming,面向切面编程)开发可以通过两种主要方式来实现:编程式和声明式。这两种方式分别对应了在代码中直接编写切面逻辑和使用特定的配置来描述切面逻辑的两种不同方式。

  1. 编程式 AOP: 编程式 AOP 是指在代码中直接编写切面逻辑。这种方式要求开发人员在代码中显式地调用切面逻辑,通常通过方法调用来实现。编程式 AOP 提供了最大的灵活性,开发人员可以精确控制切面逻辑的应用时机,但可能会导致代码冗余和可维护性降低。
  2. 声明式 AOP: 声明式 AOP 是指使用特定的配置来描述切面逻辑,而不需要在代码中显式调用切面逻辑。这种方式通过在配置文件中或使用注解来定义切面逻辑的应用时机和规则。声明式 AOP 提供了更好的可维护性和代码模块化,使切面逻辑与主要业务逻辑分离,提高了代码的可读性和可维护性。

在声明式 AOP 中,有两种常见的方式:

  • 基于 XML 配置: 在配置文件中使用 XML 描述切面逻辑的织入时机和规则,如 Spring AOP 的 XML 配置。
  • 基于注解: 使用注解来标记切面逻辑的应用时机和规则,如 Spring AOP 的基于注解的方式。

两种方式各有优势,选择哪种方式取决于项目需求和团队偏好。编程式 AOP 提供了更大的灵活性,适用于一些特定的场景。而声明式 AOP 则提供了更好的可读性和维护性,适用于大多数项目,可以更好地实现横切关注点的分离和处理。

下面着重讲解两种声明式AOP。

3、基于 XML

3.1、快速入门

基本步骤如下:

① 导入 AOP 相关坐标

② 创建目标接口和目标类(内部有切点)

③ 创建切面类(内部有增强方法)

④ 将目标类和切面类的对象创建权交给 spring

⑤ 在 applicationContext.xml 中配置织入关系

⑥ 测试代码

整体目录如下:

3.1.1、导入坐标

<!--导入aop相关坐标-->

<dependency>

   <groupId>org.springframework</groupId>

   <artifactId>spring-context</artifactId>

   <version>5.0.5.RELEASE</version>

</dependency>

<!-- aspectj的织入 -->

<dependency>

   <groupId>org.aspectj</groupId>

   <artifactId>aspectjweaver</artifactId>

   <version>1.8.13</version>

</dependency>

3.1.2、创建接口和实现类

3.1.3、创建切面

3.1.4、配置bean

3.1.5、配置织入

3.1.6、测试

3.2、切点表达式

表达式语法:

execution([修饰符] 返回值类型 包名.类名.方法名(参数))

访问修饰符可以省略

返回值类型、包名、类名、方法名可以使用星号* 代表任意

包名与类名之间一个点 . 代表当前包下的类,两个点 .. 表示当前包及其子包下的类

参数列表可以使用两个点 .. 表示任意个数,任意类型的参数列表

3.2.1、表达式举例

例:

execution(public void com.itheima.aop.Target.method())

execution(void com.itheima.aop.Target.*(..))

execution(* com.itheima.aop.*.*(..))

execution(* com.itheima.aop..*.*(..))

execution(* *..*.*(..))

下面依次解释这些切点表达式的含义:

  1. execution(public void com.itheima.aop.Target.method())
  • 匹配 com.itheima.aop 包下的 Target 类的 method 方法。
  • 该方法的修饰符为 public,返回类型为 void,不接受任何参数。
  • 表示只匹配具体的类、方法和参数。
  1. execution(void com.itheima.aop.Target.*(..))
  • 匹配 com.itheima.aop 包下的 Target 类的任何方法。
  • 该方法的修饰符不限,返回类型为 void
  • (..) 表示方法可以接受任意个数和类型的参数。
  1. execution(* com.itheima.aop.*.*(..))
  • 匹配 com.itheima.aop 包下的任何类的任何方法。
  • 方法的修饰符、返回类型和参数都不限。
  1. execution(* com.itheima.aop..*.*(..))
  • 匹配 com.itheima.aop 包及其子包下的任何类的任何方法。
  • 方法的修饰符、返回类型和参数都不限。
  1. execution(* *..*.*(..))
  • 匹配任何包下的任何类的任何方法。
  • 方法的修饰符、返回类型和参数都不限。
  • 通配符 *..* 表示任意包名和子包。

这些切点表达式用于匹配不同范围的类和方法,可以根据需要来选择最合适的表达式。在 AOP 中,切点表达式用于指定切面逻辑的应用时机,从而实现横切关注点的处理。

3.2.2、表达式抽取

当多个增强的切点表达式相同时,可以将切点表达式进行抽取,在增强中使用 pointcut-ref 属性代替 pointcut 属性来引用抽取后的切点表达式。

3.3、通知的类型

3.3.1、什么是通知

通知(Advice): 通知是切面的一个具体行为,它决定在连接点处执行何种逻辑。

通常有以下几种类型的通知:前置通知(Before)、后置通知(After)、返回通知(AfterReturning)、异常通知(AfterThrowing)和环绕通知(Around)。

通知(Advice)是 AOP 中的核心概念之一,它代表了在特定连接点(方法调用、对象实例化等)处执行的切面逻辑。通知决定了在连接点何时以及如何执行特定的操作。AOP 提供了不同类型的通知,以便在不同的执行时机应用切面逻辑,从而实现横切关注点的分离。

以下是通常在 AOP 中使用的不同类型的通知:

  1. 前置通知(Before Advice): 前置通知在目标方法执行之前执行。它通常用于执行一些准备操作,如权限检查、参数验证等。
  2. 后置通知(After Advice): 后置通知在目标方法执行之后执行,无论目标方法是否抛出异常。它常用于资源释放或记录日志等操作。
  3. 返回通知(AfterReturning Advice):返回通知在目标方法成功执行并返回结果后执行。它可以获取目标方法的返回值并进行相应处理。
  4. 异常通知(AfterThrowing Advice): 异常通知在目标方法抛出异常时执行。它可以用于捕获和处理异常,或者执行一些与异常相关的操作。
  5. 环绕通知(Around Advice):环绕通知是最强大且最灵活的通知类型。它可以完全控制目标方法的执行过程,包括在方法前后进行自定义操作,还可以选择是否调用目标方法。

这些通知类型允许开发人员根据业务需求在不同的执行时机添加切面逻辑。通过组合不同类型的通知,可以实现对应用程序的不同层面进行横切关注点的处理,如日志记录、事务管理、安全性检查等。通知是 AOP 的核心元素之一,它使得切面逻辑能够在合适的时机被织入到目标代码中,从而实现了代码的解耦和模块化。

3.3.2、如何配置

通知类型

XML 配置示例

前置通知(Before)

<aop:before method="beforeMethod" pointcut="..." />

后置通知(After)

<aop:after method="afterMethod" pointcut="..." />

返回通知(AfterReturning)

<aop:after-returning method="afterReturningMethod"

pointcut="..." returning="result" />

异常通知(AfterThrowing)

<aop:after-throwing method="afterThrowingMethod"

pointcut="..." throwing="ex" />

环绕通知(Around)

<aop:around method="aroundMethod" pointcut="..." />

4、基于注解

4.1、快速入门

基于注解的aop开发步骤:

① 创建目标接口和目标类(内部有切点)

② 创建切面类(内部有增强方法)

③ 将目标类和切面类的对象创建权交给 spring

④ 在切面类中使用注解配置织入关系

⑤ 在配置文件中开启组件扫描和 AOP 的自动代理

⑥ 测试

目录如下:

4.1.1、创建接口和实现类

4.1.2、创建切面

4.1.3、配置bean

这个时候的切面类,还只是一个普通的Bean,需要后续配置。

4.1.4、配置织入

4.1.5、组件扫描和自动代理

4.1.6、测试

4.2、注解通知类型

通知的配置语法:@通知注解(“切点表达式")

通知类型

注解

说明

前置通知

@Before

指定增强的方法在切入点方法之前执行

后置通知

@AfterReturning

指定增强的方法在切入点方法之后执行

环绕通知

@Around

指定增强的方法在切入点方法之前和之后都执行

异常抛出通知

@AfterThrowing

指定增强的方法在出现异常的时候执行

最终通知

@After

无论增强方法执行是否有异常都会执行

4.3、表达式抽取

同 xml 配置 aop 一样,我们可以将切点表达式抽取。

抽取方式是在切面内定义方法,在该方法上使用@Pointcut注解定义切点表达式,然后再在增强注解中进行引用。

具体如下:

相关文章
|
Java Spring
11Spring - 基于AspectJ的AOP开发(注解的方式)
11Spring - 基于AspectJ的AOP开发(注解的方式)
51 0
|
XML Java 数据格式
10Spring - 基于AspectJ的AOP开发 (XML的方式)
10Spring - 基于AspectJ的AOP开发 (XML的方式)
50 0
|
1月前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
40 0
|
4月前
|
XML Java 数据库
Spring5入门到实战------10、操作术语解释--Aspectj注解开发实例。AOP切面编程的实际应用
这篇文章是Spring5框架的实战教程,详细解释了AOP的关键术语,包括连接点、切入点、通知、切面,并展示了如何使用AspectJ注解来开发AOP实例,包括切入点表达式的编写、增强方法的配置、代理对象的创建和优先级设置,以及如何通过注解方式实现完全的AOP配置。
|
6月前
|
Java Spring 容器
基于注解的Aop开发,实现aop快速入门,基于注解的AOP开发
基于注解的Aop开发,实现aop快速入门,基于注解的AOP开发
|
7月前
|
Java Maven 数据安全/隐私保护
代码优雅升级,提升开发效率:挖掘Spring AOP配置的学习宝藏!
代码优雅升级,提升开发效率:挖掘Spring AOP配置的学习宝藏!
|
XML 设计模式 Java
Spring进阶-AOP注解开发
Spring进阶-AOP注解开发
159 0
|
Java Spring
Java Web实战 | Spring AOP开发
下面,通过一个案例讲授如何通过Advisor的子接口进行Spring AOP开发,步骤如下所述。
158 0
java202304java学习笔记第六十四天-ssm-aop开发明确的事项和知识要点
java202304java学习笔记第六十四天-ssm-aop开发明确的事项和知识要点
70 0
|
Web App开发 开发框架 前端开发
SpringCloud微服务实战——搭建企业级开发框架(三十九):使用Redis分布式锁(Redisson)+自定义注解+AOP实现微服务重复请求控制
通常我们可以在前端通过防抖和节流来解决短时间内请求重复提交的问题,如果因网络问题、Nginx重试机制、微服务Feign重试机制或者用户故意绕过前端防抖和节流设置,直接频繁发起请求,都会导致系统防重请求失败,甚至导致后台产生多条重复记录,此时我们需要考虑在后台增加防重设置。
585 53
SpringCloud微服务实战——搭建企业级开发框架(三十九):使用Redis分布式锁(Redisson)+自定义注解+AOP实现微服务重复请求控制