欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > Spring AOP

Spring AOP

2024/10/23 6:07:25 来源:https://blog.csdn.net/Waller_/article/details/142965452  浏览:    关键词:Spring AOP

A0P(Aspect oriented Programming)面向切面编程,一种编程范式,指导开发者如何组织程序结构

作用

在不惊动原始设计的基础上为其进行功能增强


AOP概念

连接点(JoinPoint):

  • 程序执行过程中的任意位置,粒度为执行方法、抛出异常、设置变量等,在SpringAOP中,理解为方法的执行

切入点(Pointcut):

  • 匹配连接点的式子,在springAOP中,一个切入点可以只描述一个具体方法,也可以匹配多个方法
  • 一个具体方法: com.example.dao包下的BookDao接口中的无形参无返回值的save方法
  • 匹配多个方法:所有的save方法,所有的get开头的方法,所有以Dao结尾的接口中的任意方法,所有带有一个参数的方法    

通知(Advice):

  • 在切入点处执行的操作,也就是共性功能,在SpringAOP中,功能最终以方法的形式呈现

通知类:

  • 定义通知的类

切面(Aspect):

  • 描述通知与切入点的对应关系

 

使用

<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.1.12</version>
</dependency>
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version>
</dependency>

步骤: 创建通知类->定义共享方法->定义Pointcut切入点->定义execution连接方法->将切入点与共性方法关联

注意:切入点表达式标准格式:动作关键字(访问修饰符 返回值包名.类/接口名.方法名(参数)异常名 )

通配符匹配

使用规范

所有代码按照标准规范开发,否则以下技巧全部失效

描述切入点通常描述接口,而不描述实现类

访问控制修饰符针对接口开发均采用public描述(可省略访问控制修饰符描述)

返回值类型对于增删改类使用精准类型加速匹配,对于查询类使用*通配快速描述

包名书写尽量不使用..匹配,效率过低,常用*做单个包描述匹配,或精准匹配

接口名/类名书写名称与模块相关的采用*匹配,例如UserService书写成*Service,绑定业务层接口名

方法名书写以动词进行精准匹配,名词采用*匹配,例如getByld书写成getBy*,selectAll

书写成selectAl参数规则较为复杂,根据业务方法灵活调整

通常不使用异常作为匹配规则
 

AOP工作流程

1.读取所有切面中定义的切入点

2.初始化bean,判断bean对应的类中的方法是否匹配到了切入点,若有方法匹配了切入点,则创建原始对象(目标对象)的代理对象

  • 如上述案例中,spring初始化BookDaoImpl类的时候会检查类中的方法,是否有与切入点关联的方法

AOP通知类型

AOP通知描述了抽取的共性功能,根据共性功能抽取的位置不同,最终运行代码时要将其加入到合理的位置
AOP通知共分为5种类型

  • 前置通知
  • 后置通知
  • 环绕通知(重点 )
  • 返回后通知(了解)
  • 抛出异常后通知(了解 )
     
package org.example.aop;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;@Component
@Aspect
public class MyAdvice {@Pointcut("execution(void org.example.dao.BookDao.update())")private void pt() {}// 前置通知@Before("pt()")public void before() {System.out.println(System.currentTimeMillis());}// 后置通知@After("pt()")public void after() {System.out.println(System.currentTimeMillis());}// 环绕通知@Around("pt()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable { //由于无法预知原始方法运行后是否会抛出异常,因此环绕通知方法必须抛出Throwable对象System.out.println("before");Object ret = joinPoint.proceed(); // 标识对原始操作的调用,这里的原始操作是指 update() 方法System.out.println("after");return ret;}// 返回后通知: 最终方法正常执行完后@AfterReturning("pt()")public void afterReturning() {System.out.println(System.currentTimeMillis());}// 抛出异常后通知:最终方法抛出异常后执行@AfterThrowing("pt()")public void afterThrowing() {System.out.println(System.currentTimeMillis());}}

AOP获取参数和返回值

JoinPoint 类用在 前置通知、后置通知、返回后通知、抛出异常后通知 的方法中获取最终方法的参数ProceedingJoinPoint 类在 环绕通知 的方法中获取最终方法的参数

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com