> 文章列表 > 【Java Web】013 -- SpringBootWeb综合案例(事务管理、AOP)

【Java Web】013 -- SpringBootWeb综合案例(事务管理、AOP)

【Java Web】013 -- SpringBootWeb综合案例(事务管理、AOP)

目录

一、事务管理

1、事务回顾

①、概念与操作

2、Spring事务管理(@Transactional)

①、案例:解散部门(删除部门,同时删除该部门下的员工)

②、@Transactional注解

③、开启事务管理日志开关(application.yml)

3、事务进阶(@Transactional注解的两个属性)

①、rollbackFor

②、propagation(传播行为)

③、案例:解散部门时,记录操作日志到数据库表中

④、小结

二、AOP基础

1、AOP概述

2、AOP快速入门

①、入门案例

②、AOP应用场景与优势

③、小结

3、AOP核心概念

①、连接点:JoinPoint

②、通知:Advice

③、切入点:PointCut

④、切面:Aspect

⑤、目标对象:Target

⑥、AOP执行流程

⑦、小结

三、AOP进阶

1、通知类型

①、通知类型示例

②、@PointCut注解:抽取公共切点表达式

③、小结

2、通知顺序

①、类名字母排序

②、@Order注解加在切面类上控制顺序

3、切入点表达式

①、切入点表达式 - execution

②、如何通过一个切入点表达式,来描述两个方法呢?

③、execution表达式 -- 小结

④、切点表达式 -- @annotation

⑤、小结

4、连接点

四、AOP案例

1、案例介绍

2、思路分析

3、实现步骤


一、事务管理

1、事务回顾

①、概念与操作

2、Spring事务管理(@Transactional)

①、案例:解散部门(删除部门,同时删除该部门下的员工)

正常示例:

Ⅰ、在EmpMapper.java中添加删除部门员工方法:

Ⅱ、在EmpService中添加方法:

Service实现类:

异常示例:

我们通过@Transactional注解可以完成对事务的控制,从而将删除部门和删除部门下员工这两个操作划分到一个事务中来,即要么同时成功,要么同时失败。

②、@Transactional注解

我们直接在ServiceImpl中的方法上加上@Transactional注解即可

③、开启事务管理日志开关(application.yml)

3、事务进阶(@Transactional注解的两个属性)

默认情况下,只有出现运行时异常,才会回滚异常,如果不是,则不会回滚,那么我们可以通过rollbackFor来指定控制的异常类型,从而实现非运行时异常的回滚。

①、rollbackFor

示例:

在ServiceImpl方法的@Transactional上指定异常的类型:

②、propagation(传播行为)

③、案例:解散部门时,记录操作日志到数据库表中

IDEA控制台日志过滤插件:

示例:

Ⅰ、准备好日志记录表(dept_log):

Ⅱ、修改DeptServiceImpl.java:

Ⅲ、添加DeptLogMapper方法:

这里的delete方法与insert方法共用一个事务:

Mapper方法:

Ⅳ、为了完成案例需求,我们应该将insert方法的propagation属性设为 REQUIRES_NEW

这样就使得insert方法会新创建一个事务,而不加入已有的delete事务中

④、小结

二、AOP基础

1、AOP概述

我们可以将业务方法抽取成模板方法:

而这种模板方法的实现方法就是:动态代理

2、AOP快速入门

①、入门案例

示例:

Ⅰ、导入依赖:

Ⅱ、编写AOP程序:

@Aspect注解:用来标识当前类是一个AOP类

Ⅲ、运行测试:

②、AOP应用场景与优势

③、小结

3、AOP核心概念

①、连接点:JoinPoint

可以被AOP控制的方法(暗含方法执行时的相关信息),连接点指的是可以被aop控制的方法。例如:入门程序当中所有的业务方法都是可以被aop控制的方法。

在SpringAOP提供的JoinPoint当中,封装了连接点方法在执行时的相关信息。

②、通知:Advice

通知,指哪些重复的逻辑,也就是共性功能(最终体现为一个方法)。

在入门程序中是需要统计各个业务方法的执行耗时的,此时我们就需要在这些业务方法运行开始之前,先记录这个方法运行的开始时间,在每一个业务方法运行结束的时候,再来记录这个方法运行的结束时间。

但是在AOP面向切面编程当中,我们只需要将这部分重复的代码逻辑抽取出来单独定义。抽取出来的这一部分重复的逻辑,也就是共性的功能。

③、切入点:PointCut

切入点,匹配连接点的条件,通知仅会在切入点方法执行时被应用

在通知当中,我们所定义的共性功能到底要应用在哪些方法上?此时就涉及到了切入点pointcut概念。切入点指的是匹配连接点的条件。通知仅会在切入点方法运行时才会被应用。

​在aop的开发当中,我们通常会通过一个切入点表达式来描述切入点(后面会有详解)

假如:切入点表达式改为DeptServiceImpl.list(),此时就代表仅仅只有list这一个方法是切入点。只有list()方法在运行的时候才会应用通知。

④、切面:Aspect

切面,描述通知与切入点的对应关系(通知+切入点)

当通知和切入点结合在一起,就形成了一个切面。通过切面就能够描述当前aop程序需要针对于哪个原始方法,在什么时候执行什么样的操作。

切面所在的类,我们一般称为切面类(被@Aspect注解标识的类)

⑤、目标对象:Target

目标对象指的就是通知所应用的对象,我们就称之为目标对象。

⑥、AOP执行流程

Spring的AOP底层是基于动态代理技术来实现的,也就是说在程序运行的时候,会自动的基于动态代理技术为目标对象生成一个对应的代理对象。在代理对象当中就会对目标对象当中的原始方法进行功能的增强。

⑦、小结

三、AOP进阶

1、通知类型

注意事项:(@Around环绕通知)

①、通知类型示例

示例:

@Before:前置通知,在目标方法前被执行

@Around:环绕通知,在目标方法前、后都被执行

@After:后置通知,在目标方法后被执行

@AfterReturning:返回后通知,此注解标注的通知方法在目标方法后被执行

@AfterThrowing:异常后通知,此注解标注的通知方法发生异常后执行

②、@PointCut注解:抽取公共切点表达式

解决大量重复的切入点表达式:(抽取)

 

如果切入点表达式需要改动,那么只需要改动最上面的就可以了

③、小结

@AfterReturning与@AfterThrowing注解互斥,返回后通知,有异常不会执行;异常后通知,只有异常时才会通知

2、通知顺序

 

 

①、类名字母排序

通知顺序与类名有关:

类名越靠前,前置通知则越先执行,后置通知则越后执行

②、@Order注解加在切面类上控制顺序

3、切入点表达式

 

①、切入点表达式 - execution

示例:

全类名不建议省略,因为一旦省略,这个范围就有些过大,从而影响效率

 

通配符:

示例:

*:单个独立的任意符号,可以通配任意返回值、包名、类名、方法名、任意类型的一个参数

 

..:多个连续的任意符号,可以通配任意层级的包,或任意类型、任意个数的参数

②、如何通过一个切入点表达式,来描述两个方法呢?

我们可以一个一个来描述:

③、execution表达式 -- 小结

书写建议:

④、切点表达式 -- @annotation

示例:

通过@annotation表达式来简化切入点表达式描述多个方法的操作:

Ⅰ、创建一个自定义注解:

Ⅱ、给想切入的方法上加上注解:

Ⅲ、编写切入点表达式:

⑤、小结

4、连接点

示例:@Around通知

运行结果:

四、AOP案例

1、案例介绍

2、思路分析

@annotation解决目标方法匹配:

3、实现步骤

示例:

Ⅰ、引入AOP起步依赖:

 

Ⅱ、导入数据库表,引入对应的实体类

创建操作日志表(operate_log):

引入实体类(OperateLog):

 

Ⅲ、引入Mapper接口:

OperateLogMapper:

 

Ⅳ、自定义Log注解,仅起到标识方法的作用,不需要指定属性:

anno:

Ⅴ、定义一个切面类:

LogAspect:

代码实现细节: 获取request对象,从请求头中获取到jwt令牌,解析令牌获取出当前用户的id。

Ⅵ、启动服务、进行测试:

数据库表数据:(增、删、改)