首页 > 编程语言 >深入理解 Spring AOP:面向切面编程的原理与应用

深入理解 Spring AOP:面向切面编程的原理与应用

时间:2024-11-03 12:51:58浏览次数:3  
标签:Spring 切入点 bean 切面 AOP 注解 方法 表达式

一、概述

AOP(Aspect Orient Programming)是一种设计思想,是软件设计领域中的面向切面编程,它是面向对象编程(OOP)的一种补充和完善。它以通过预编译方式和运行期动态代理方式,实现在不修改源代码的情况下给程序动态统一添加额外功能的一种技术。

(一)AOP与OOP之间的区别

OOP:将面向对象理解为一个静态过程(例如一个系统有多少个模块,一个模块有哪些对象,对象有哪些属性),

AOP:面向切面的运行期代理方式,理解为一个动态过程,可以在对象运行时动态织入一些扩展功能或控制对象执行。

(二)AOP的运用场景

实际项目中通常会将系统分为两大部分,一部分是核心业务,一部分是非核业务。在编程实现时我们首先要完成的是核心业务的实现,非核心业务一般是通过特定方式切入到系统中,这种特定方式一般就是借助AOP进行实现。

(三)AOP原理与术语

Aop运行原理:

Aop术语:

切面(Aspect):一个使用@Aspect注解描述的类的对象。@

通知(Advice):在切面上某一特定的连接点上要执行的使用特定通知注解描述的方法。一般用于提供非核心事务。

连接点(JoinPoint):程序执行过程中某个特定的运行节点。程序运行到该节点前后会执行通知方法。

切入点(PointCut):对多个连接点的一种定义,一般可以理解为多个连接点的集合。

连接点与切入点:

连接点可以理解为被代理类的每个被拦截的方法。

切入点可以理解被拦截的类。使用@Pointcut注解通过切入点表达式定义。

二、开发步骤

(一)原理:

通过@Aspect注解标识AOP中的切面类型,基于切面类型构建的对象用于为目标对象进行功能扩展或控制目标对象的执行。

通过@Pointcut注解描述切面中的一个特定方法结合实参(切入点表达式)来定义切入点(连接点集合)。该特定方法无实际意义,但不可或缺,其主要作用是承载@Pointcut注解。​​​​​​​

通过5种通知注解描述切面方法,这些方法用于进行功能扩展或控制目标对象的招待。

其中@Around描述的方法最为特殊,方法用于控制目标方法的执行。即,目标方法的执行是从@Around描述的方法开始,并从@Around描述的方法结束。在@Around方法执行过程中会调用其它4种通知注解描述的通知方法。

该注解描述的方法需要ProceedingJoinPoint类型的形参。该类型定义了一个连接点。该类型的对象用于封装要执行的目标方法相关的信息。该类型的对象只能作为@Around注解描述的方法的形参。

其余4种通知方法通常用于扩展功能。

此4种通知所描述的方法只能使用JoinPoin类型形参来定义目标方法。

特别注意

JoinPoin的包为:org.aspectj.lang.JoinPoint;千万不能引错包。

当JoinPoin引成:org.aopalliance.intercept.Joinpoint;时

(二)所需依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

(三)开发步骤

(四)五种通知方法的执行流程

三、开发增强

(一)通知增强

1.作用:通知注解主要用于描述控制目标方法执行或对目标方法进行扩展的方法。

2.通知分类:

在基于Spring Aop编程的过程中,基于AspectJ框架标准,Spring中定义了五种类型的通知:

@Around:访问目标类或方法之前进入该注解描述的方法。

@Before:如果存在该注解描述的方法,则在@Around描述的方法中,调用(ProceedJoinPoint)jp.proceed()方法(即目标方法)之前调用该注解描述的方法。

@AfterReturning:如果存在该注解描述的方法,则在jp.proceed()方法成功执行之后立即执行该注解描述的方法。

@AfterThrowing:如果存在该注解描述的方法,则在jp.proceed()方法异常之后立即执行该注解描述的方法。

@AfterThrowing注解常用属性:

value属性:用于指定切入点表达式或切入点表达式的引用。

throwing属性:指定要处理的异常。该属性的属性值必须与描述方法的异常参数名相同。如果不同则会抛出异常如下图所示:

@After:如果存在该注解描述的方法,@AfterReturning|@AfterThrowing描述的方法执行之后执行该注解描述的方法。

当@After注解描述的方法执行之后,程序会将控制权交还于@Around描述的方法,继续执行@Around描述的方法后续语句。

使用说明:

在切面类中使用什么通知,由业务决定,并不需要把所有通知都写入切面类。

3.通知注解使用方式:

方式一:可以通过切入点表达式作为实参直接传递给通知注解的方式使用。

应用场景:一个切面类中需要处理的连接点的通知方法较少时可以使用该方式。

特点:使用该方式时,省略由此类连接点组成的切入点的定义。

方式二:可以通过将切入点表达式的引用作用实参传递给注解的方式使用。

应用场景:一个切面类中需要处理的连接点的通知方法较多。

特点:

使用该方式时,需要使用@Pointcut注解定义此类连接点构成的切入点。该注解的实参则为切入点表达式。

而切入点表达式的引用即为:@Pointcut注解描述的方法。

(二)切入点表达式增强

1.作用:用于指定要扩展功能的类或方法。

2.分类:

bean表达式:用于匹配指定bean对象的所有方法。​​​​​​​

within表达式:用于匹配包下所有类内的所有方法。​​​​​​​

excution表达式:用于按指定语法规则匹配到具体方法。​​​​​​​

@annotation表达式:用于匹配指定注解描述的方法。

3.使用位置:

位置一:切入点表达式做为实参赋值于@Pointcut注解的value属性。

示例:@Pointcut("bean(goodsSvsImpl)")

位置二:切入点表达式做为实参赋值给通知注解。

示例:@Around("bean(goodsSvsImpl)")

4.bean表达式(重点):

应用场景:

bean表达式一般应用于类级别,实现粗粒度的切入点表达式的定义。

使用方式:

方式一:通过具体bean对象定义切入点。

示例:bean("userServiceImpl")。

特点:此时的切入点则由该对象的所有方法对应的连接点组成。

方式二:通过通配符*带指定后缀的bean对象定义切入点。

示例:bean("*ServiceImpl")。

特点:此时的切入点则由带后缀的所有bean对象中的所有方法对应的连接点组成。

使用说明:

如果通过具体bean对象指定切入点表达式时,则该bean对象是由Spring容器管理的一个bean对象,表达式内部的名字应该是Spring容器中某个bean的name。(Spring管理的bean对象的命名规则:在默认情况下,Spring管理的bean对象名字是其类名首字母小写)。

5.within表达式(了解):

应用场景:

within表达式应用于包、类级别,实现粗粒度的切入点表达式的定义。

使用方式:

within("aop.service.UserSvsImpl"):指定包中具体类的所有方法对应的连接点构成的切入点。

within("aop.service.*"):指定当前包下的所有类的所有方法对应的连接点构成的切入点。

within("aop.service..*"):指定当前包及其子包中所有类的所有方法对应的连接点构成的切入点。

使用说明:

如果within应用于类级别时,此时,表达式中的类名必须是类名,不是Spring管理的该类的对象的名字。

适用场景:

对所有业务bean都要进行功能增强,但是bean名字没有规则。

按业务模块(不同包下的业务)对bean对象进行业务功能增强。

6.execution表达式(重点):

应用场景:

execute表达式应用于方法级别,实现细粒度的切入点定义。

语法:

execute(returnType packageName.className.methodName([paramList]))。

示例:

execution(void aop.service.UserServiceImpl.addUser())匹配addUser方法。

execution(void aop.service.PersonServiceImpl.addUser(String)) 方法参数必须为String的addUser方法。

execution(* aop.service..*.*(..)) 万能配置。

7. @annotation表达式(重点):

应用场景:

@annotation表达式应用于方法级别,实现细粒度的切入点表达式定义。

开发步骤:

第一步:定义自定义注解。

第二步:使用自定义注解描述要拦截的目标方法。

第三步:使用@annotation(自定义注解)定义切入点表达式,并使用该切面表达式赋值给通知注解和定义扩展功能的方法。

(三)切面优先级设置实现

(四)Spring AOP关键对象与术语总结

四、SpringAOP数据库事务管理

(一)SpringAOP数据库事务管理方式

1.声明式数据库事务管理原理

默认情况下,如果被注解的数据库操作方法中发生了unchecked异常,所有的数据库操作将rollback;如果发生了checked异常,则该数据库操作还是会提交commit。​​​​​​​

checked异常:通常是Exception类的子类(非RuntimeException类)

表示无效,不是程序中可以预测的。比如无效的用户输入,文件不存在,网络或数据库链接错误等不由程序内部控件产生的异常。

此类异常必须在代码中显式处理。使用try-catch或throw方式。

定义此类异常必须继承Exception类。

unchecked异常:通常是RuntimeException类的子类。

表示程序逻辑错误。

不需要在代码中显式地捕获处理此类异常。

2.Spring声明式数据库事务管理方法:

通过start transaction|begin显示开启事务​​​​​​​

通过commit|rollback结束事务。​​​​​​​

MySql数据库默认开启数据库事务,通过手动提交或执行回滚来结束事务。

3.Spring事务管理特点

Spring的事务管理是线程安全的。​​​​​​​

事务方法的嵌套调用会产生事务传播。​​​​​​​

父类声明的@Transaction会对子类的所有方法进行事务增强。子类覆盖重写父类方式可覆盖其@Transaction中的声明配置。​​​​​​​

当@Transaction描述类时,类中的方法可以通过属性配置来覆盖类上的@Transaction配置。(类上配置全局是可读写,可在某个方法上改为只读)

(二)@Transaction实现声明式数据库事务管理

1.@Transaction注解属性

属性说明:

2.使用规则

描述对象:接口、接口方法和实现类、接口实现方法。

Spring团队建议:该注解应用于描述实现类或实现类的方法。在接口上使用时,只能当设置了基于接口的代理时,该注解才生效。

方法的访问权限:该注解只能描述public修饰的方法。​​​​​​​

@Transaction的事务开启是基于接口的或者是基于类的代理对象被创建。因此在同一个类中的一个方法调用另一个带事务的方法时,将不会开启事务。​​​​​​​

多线程下事务管理因为线程不属于Spring托管,故线程不能够默认使用Spring事务,也不能获取Spring注入的Bean。​​​​​​​

在被Spring声明式事务管理的方法内开启多线程,多线程内的方法不被事务控制。​​​​​​​

一个使用了@Transaction的方法,如果方法内包含多线程的使用,方法内部出现异常,不会回滚线程中调用方法的事务。

3.@Transaction 注解的实质

该注解使用JDBC的事务方式进行事务管理。并通过动态代理机制实现。

(三)Spring事务特性

1.实现事务的隔离级别

通过@Transaction的isolation属性指定。​​​​​​​

实现示例:

2.实现事务传播行为:

通过@Transaction的propagation属性指定。​​​​​​​

实现方式:

​​​​​​​

事务嵌套:

(四)Spring事务回滚规则

(五)多线程事务管理

标签:Spring,切入点,bean,切面,AOP,注解,方法,表达式
From: https://blog.csdn.net/h123372868/article/details/143464020

相关文章

  • 技术驱动教育:SpringBoot在线试题库解决方案
    1绪论1.1研究背景现在大家正处于互联网加的时代,这个时代它就是一个信息内容无比丰富,信息处理与管理变得越加高效的网络化的时代,这个时代让大家的生活不仅变得更加地便利化,也让时间变得更加地宝贵化,因为每天的每分钟,每秒钟这些时间都能让人们处理大批量的日常事务,这些场......
  • SpringBoot实战:打造高效在线试题库
    1绪论1.1研究背景现在大家正处于互联网加的时代,这个时代它就是一个信息内容无比丰富,信息处理与管理变得越加高效的网络化的时代,这个时代让大家的生活不仅变得更加地便利化,也让时间变得更加地宝贵化,因为每天的每分钟,每秒钟这些时间都能让人们处理大批量的日常事务,这些场......
  • 一文彻底弄懂Spring IOC 依赖注入
    SpringIOC(InversionofControl,控制反转)依赖注入是Spring框架的核心特性之一,旨在实现对象之间的松耦合,提升代码的可维护性、可测试性和可扩展性。下面我们将从以下几个方面深入探讨SpringIOC依赖注入的机制和实现原理。一、基本概念控制反转(InversionofControl)控制反......
  • SpringBoot实现:高效在线试题库系统
    1绪论1.1研究背景现在大家正处于互联网加的时代,这个时代它就是一个信息内容无比丰富,信息处理与管理变得越加高效的网络化的时代,这个时代让大家的生活不仅变得更加地便利化,也让时间变得更加地宝贵化,因为每天的每分钟,每秒钟这些时间都能让人们处理大批量的日常事务,这些场......
  • 智能教育工具:基于SpringBoot的在线试题库
    1绪论1.1研究背景现在大家正处于互联网加的时代,这个时代它就是一个信息内容无比丰富,信息处理与管理变得越加高效的网络化的时代,这个时代让大家的生活不仅变得更加地便利化,也让时间变得更加地宝贵化,因为每天的每分钟,每秒钟这些时间都能让人们处理大批量的日常事务,这些场......
  • Springboot使用 jenkins-client 调用Jenkins REST API教程和构建 build时 报错 403
    前言:最近在工作中,遇到一个需求,使用java调用Jenkins进行全自动测试的需求于是在网上查找大量资料,可以使用jenkins-client这个工具可以调用JenkinsRESTAPI在执行GET请求获取Jenkins信息的时候没有任何问题,但是执行POST请求时,比如build构建job,create创建jo......
  • 基于SpringBoot + Vue的宾馆客房管理系统(角色:用户、员工、管理员)
    文章目录前言一、详细操作演示视频二、具体实现截图三、技术栈1.前端-Vue.js2.后端-SpringBoot3.数据库-MySQL4.系统架构-B/S四、系统测试1.系统测试概述2.系统功能测试3.系统测试结论五、项目代码参考六、数据库代码参考七、项目论文示例结语前言......
  • 基于SpringBoot+Vue的广东省家庭旅游接待信息管理系统(源码+LW+调试文档+讲解)
    项目简介背景随着旅游业的蓬勃发展,家庭旅游在广东省越来越受欢迎。家庭旅游接待作为一种特色旅游模式,为游客提供了独特的体验,但目前在信息管理方面存在诸多不足。一方面,家庭旅游接待户信息分散,包括接待能力、服务项目、价格、地理位置等信息缺乏统一的收集和整理渠道,游客......
  • 基于SpringBoot+Vue的公司考勤管理系统(源码+LW+调试文档+讲解)
    项目简介背景在公司日常运营中,考勤管理是人力资源管理的重要组成部分。随着公司规模的扩大和业务模式的多样化,传统的考勤方式(如人工签到、纸质打卡)暴露出诸多问题。一方面,这些方式效率低下,容易造成员工上下班打卡拥堵,浪费时间。另一方面,数据统计和分析困难,考勤数据易丢失......
  • 基于SpringBoot+Vue的公司财务管理系统(源码+LW+调试文档+讲解)
    项目简介背景在公司运营过程中,财务管理至关重要且复杂度高。随着公司规模的扩大和业务的拓展,财务数据量急剧增加,包括收入、支出、资产、负债、现金流等各类信息。传统的财务管理方式多依赖手工记账和简单的电子表格,存在数据处理效率低、易出错、数据安全性差等问题。不同......