Spring(二)AOP、切入点表达式、AspecJ常用通知的类型、Spring中的事务管理

ops/2024/12/19 19:47:01/

文章目录

一、AOP

1、定义

2、特点

3、AOP中的术语(连接点、切入点、通知、目标、代理)

4、配置

(1)下载AOP相关jar

(2)启动AspectJ支持

5、使用

6、切入点表达式

 7、AspecJ常用通知的类型

(1)@Before 前置通知,在我们的方法实际执行前调用

(2)@After 后置通知,在我们的方法实际执行之后调用,与是否出现异常无关

(3)@AfterReturning 返回通知,在我们的方法执行之后调用,如果出现异常不再执行

(4)@After Throwing 异常通知,在切入点出现异常之后调用

(5)@Around 环绕通知,可以在我们要增强的方法执行之前、之后、出现异常时添加功能,其中ProceedingJoinPoint表示我们要增强的方法

二、Spring中的事务管理

1、什么是数据库事务?

2、为什么需要数据库事务?

3、Spring中的事务管理的形式

(1)形式一:编程式事务管理

(2)形式二:声明式事务管理

方式一:基于xml配置

方式二:基于注解实现

(3)基于注解实现的声明式事务管理的配置和实现

4、Spring中声明式事务管理失效的场景:


一、AOP

1、定义

AOP是Aspect Oriented Programming的缩写,意为面向切面编程,是一种将非业务代码和业务代码进行分离的一种思想。在实际开发中,有许多重复性的操作,例如事务提交、权限认证、保存日志等,需要在业务代码中重复被调用。面向切面编程,就是对非业务代码进行抽取,然后在不修改原有代码的前提下,为业务代码添加额外的功能。AOP底层使用的是动态代理技术,让一个代理对象,帮助我们调用非业务代码。

2、特点

AOP不是Spring的,而是java中的动态代理模式,是Spring使用了这一思想。

3、AOP中的术语(连接点、切入点、通知、目标、代理)

(1)连接点:类中可以被增强(添加额外功能)的方法。

(2)切入点:类中实际被增强的方法。

(3)通知:指一个切面在特定的连接点要做的事情(要增强的功能)。分为方法执行前通知、方法执行后通知、环绕通知等。

(4)目标:代理的目标对象,具体指连接点或切入点所在的类

(5)代理(Proxy):向目标对象应用通知时所创建的代理对象(目前使用的代理对象由Spring框架直接生成,我们不需要关心)

4、配置

(1)下载AOP相关jar

<!--AOP相关jar-->
<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.2.2.RELEASE</version>
</dependency>

(2)启动AspectJ支持

<aop:aspectj-autoproxy />

5、使用

java">@Component //spring管理生成CommonUtil类的对象
@Aspect //添加此标签的类中的方法可以被代理调用
public class CommonUtil {/*@Before("execution(* com.ffyc.springpro.dao.AdminDao.*(..))") AdminDao中的所有方法*//*@Before("execution(* com.ffyc.springpro.dao.AdminDao.saveAdmin(..))") AdminDao中的所有saveAdmin方法*//*@Before("execution(* com.ffyc.springpro.dao.AdminDao.saveAdmin())") AdminDao中的无参的saveAdmin方法*//*@Before("execution(* com.ffyc.springpro.dao.AdminDao.saveAdmin(String))") AdminDao中的指定参数的saveAdmin方法*/@Before("execution(* com.ffyc.springpro.dao.AdminDao.saveAdmin(..))")public void saveLog(){System.out.println("方法执行成功");}public void commit(){System.out.println("提交事务");}
}

6、切入点表达式

 7、AspecJ常用通知的类型

(1)@Before 前置通知,在我们的方法实际执行前调用

java">@Before("execution(* com.ffyc.springpro.dao.*.*(..))")public void saveLog(){System.out.println("方法执行成功");}

(2)@After 后置通知,在我们的方法实际执行之后调用,与是否出现异常无关

java">@After("execution(* com.ffyc.springpro.dao.*.*(..))")public void commit(){System.out.println("提交事务");}

(3)@AfterReturning 返回通知,在我们的方法执行之后调用,如果出现异常不再执行

java">@AfterReturning("execution(* com.ffyc.springpro.dao.*.*(..))")public void commit(){System.out.println("提交事务");}

(4)@After Throwing 异常通知,在切入点出现异常之后调用

java">@AfterThrowing(value = "execution(* com.ffyc.springpro.dao.*.*(..))",throwing = "e")public void exception(Throwable e){System.out.println("系统出现异常"+e.getMessage());}

(5)@Around 环绕通知,可以在我们要增强的方法执行之前、之后、出现异常时添加功能,其中ProceedingJoinPoint表示我们要增强的方法

java">@Around("execution(* com.ffyc.springpro.dao.*.*(..))")public void aroundAdvice(ProceedingJoinPoint joinPoint){try {System.out.println("打印日志");// 前置通知Object[] args = joinPoint.getArgs();// 获取自己的方法中的参数System.out.println(Arrays.toString(args));joinPoint.proceed();// 调用自己的方法System.out.println("提交事务");// 返回通知}catch (Throwable throwable) {System.out.println("系统出现异常:"+throwable.getMessage());// 异常通知}System.out.println("后置通知/最终通知");// 后置通知}

二、Spring中的事务管理

1、什么是数据库事务?

数据库事务是对数据库一次执行的若干操作所进行的管理,数据库一次执行的若干操作就是若干条sql语句,是一个整体单元。

例如:转账

语句1:从A账户减钱

语句2:向B账户加钱

那么这两个语句必须是一个整体,要么都执行,要么都不执行。

2、为什么需要数据库事务?

为了保证数据的完整性,不能一半保存到数据库,一半没保存到数据库。

之前在jdbc中是每次执行完sql之后事务是自动进行提交的。(自动提交是有风险的)

mybatis中是手动使用sqlSession.commit()提交事务的。(操作麻烦)

3、Spring中的事务管理的形式

(1)形式一:编程式事务管理

需要我们在代码中需要提交事务或回滚事务的位置写代码实现

(2)形式二:声明式事务管理

建立在 AOP 基础上,本质上是对方法前后进行拦截,所以声明式事务管理是方法级别的。声明式事务管理实现方式有两种

  • 方式一:基于xml配置
  • 方式二:基于注解实现

Spring 的 dao 框架,提供事物管理实现类DataSourceTransactionManager

(3)基于注解实现的声明式事务管理的配置和实现

<!-- 配置 spring 事务管理器-->
<bean id="transactionManager" 
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
  • 开启注解事务管理
<tx:annotation-driven transaction-manager="transactionManager"/>
  • 在类或方法上使用@Transactional 标签

如果在方法上面添加@Transactional 标签,那么该方法将会在Spring事务管理对象的管理下执行

java">@Transactionalpublic void save(){loginDao.insertAdmin1();System.out.println(10/0);loginDao.insertAdmin2();}

如果在类上面添加@Transactional 标签,那么该类中的所有方法都将会在Spring事务管理对象的管理下执行

java">@Service (value = "loginService")
@Transactional
public class LoginService {@AutowiredLoginDao loginDao;public Admin login(Admin admin){Admin admin1 = loginDao.login(admin);return admin1;}public void save(){loginDao.insertAdmin1();System.out.println(10/0);loginDao.insertAdmin2();}
}

4、Spring中声明式事务管理失效的场景:

(1)@Transactional添加在了非public的方法的上面

(2)方法在执行时异常被catch捕获了,声明式事务管理认为方法没有出现异常

(3)方法中在执行时出现编译期异常

解决方案:在@Transactional(rollbackFor = RuntimeException.class)中设置允许回滚的异常类型为Exception,即@Transactional(rollbackFor = Exception.class)

(4)数据库引擎不支持事务,比如mysql数据库中的MyISAM引擎。

解决方案:将mysql数据库中的引擎改为InnoDB


http://www.ppmy.cn/ops/143275.html

相关文章

二、windows环境下vscode使用wsl教程

本篇文件介绍了在windows系统使用vscode如何连接使用wsl&#xff0c;方便wsl在vscode进行开发。 1、插件安装 双击桌面vscode&#xff0c;按快捷键CtrlShiftX打开插件市场&#xff0c;搜索【WSL】点击安装即可。 2、开启WSL的linux子系统 点击左下方图标【Open a Remote Win…

linux 免密远程到多个服务器如何实现

要实现从主机 192.168.1.2 免密远程连接到 192.168.1.3 和 192.168.1.4&#xff0c;您可以使用 SSH 密钥对进行身份验证。以下是详细的步骤&#xff1a; 步骤 1&#xff1a;生成 SSH 密钥对 在 192.168.1.2 主机上生成 SSH 密钥对&#xff08;如果您尚未生成过&#xff09;&a…

深入了解AI编程工具Cursor:智能编程的未来

随着人工智能技术的不断发展&#xff0c;AI 编程工具的出现极大地提升了开发者的编程效率和代码质量。**Cursor** 是其中一款备受关注的 AI 编程工具&#xff0c;它通过智能代码补全、错误提示、代码优化和自动生成等功能&#xff0c;为开发者提供了前所未有的编程体验。在本文…

【MySQL】优雅的使用MySQL实现分布式锁

MySQL实现分布式锁 引言二、基于唯一索引2.1、实现思路2.2、代码实现2.3、 测试代码2.4、小结 三、基于悲观锁3.1 、实现思路3.2、代码实现3.3、测试代码3.4、小结 四、基于乐观锁4.1 、实现思路4.2 、代码实现4.3 、测试代码4.4、小结 总结 引言 在文章《Redis实现分布式锁详…

一、LRU缓存

LRU缓存 1.LRU缓存介绍2.LRU缓存实现3.LRU缓存总结3.1 LRU 缓存的应用3.2 LRU 缓存的优缺点 1.LRU缓存介绍 LRU是Least Recently Used 的缩写&#xff0c;意为“最近最少使用”。它是一种常见的缓存淘汰策略&#xff0c;用于在缓存容量有限时&#xff0c;决定哪些数据需要被删…

mysql,创建数据库和用户授权核心语句

一.库操作1.创建库create database if not exists 库名 default 字符集 default 校对规则2.删除库drop database if exists 库名3.修改库的,字符集,校对规则alter databse 库名 default 字符集 default 校对规则4.查看当前使用的库seclect databse();5.查看库show databases;…

MTU MSS

目录 一、MTU\MSS是什么二、为什么三次握手协商MSS 一、MTU\MSS是什么 MTU : Maximum Transmission Unit,即最大传输单元&#xff0c;表示数据链路层可以传输的最大数据包&#xff08;不包含帧首部和尾部&#xff09;。 MSS : Maximum Segment Size,即最大报文段长度。MSS是TC…

最新ubuntu20.04安装docker流畅教程

最新ubuntu20.04安装docker流畅教程 使用清华镜像源 //编辑/etc/apt/sources.list # 默认注释了源码镜像以提高 apt update 速度&#xff0c;如有需要可自行取消注释 deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse # deb-sr…