SpringBoot:事务和AOP

事务

一组操作的集合,不可分割的工作单位,会被一起提交或撤销

要么同时成功,要么同时失败

实物操作

begin/start transaction 开启事务

commit 提交事务

rollback 回滚事务

eg:当我们需要保证数据的一致性,例如在删除时,删除了部门,却没有删除部门的员工,就会出现数据的不一致

此时就需要使用事务

Spring事务管理

@Transactional

在业务(service)层的方法,类,接口上

将当前方法交给Spring进行事务管理,执行前开启事务,成功执行提交事务,出现异常回滚事务.

复制代码

事务进阶

rollbackfor

@Transactional的一个属性,接收异常的字节码文件

可以控制在什么异常类型下会回滚事务,默认情况下会在RuntimeException下回滚事务.

在任意异常下回滚事务:

java 复制代码
@Transactional(rollbackFor = Exception.class)
propagation

@Transactional的一个属性,接收事务的传播行为方式

事务传播行为:指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行事务控制.

如果没有配置事务传播行为,则默认事务传播行为为REQUIRED,如果多个方法的事务传播行为相同就可以进行统一的提交和回滚.

配置事务行为
java 复制代码
REQUIRE(常用)
//默认值,需要事务,有就加入,没有就创建新事务
REQUIRE_NEW(常用)
//需要新事务,无论有无,总是创建新事务
SUPPORTS
//支持事务,有则加入,没有就在独立连接中运行SQL
NOT_SUPPORTED
//不支持事务,不加入,在独立连接中运行SQL
MANDATORY
//必须有事务,否则抛出异常
NEVER
//必须没有事务,否则抛出异常
NESTED
//嵌套事务(仅对DataSourseTransactionManager有效)

REQUIRED:在大部分情况下适用

REQUIRED_NEW:不希望事务之间相互影响时使用

AOP

Aspect Oriented Programming(面向切面编程)

将重复的逻辑剥离出来,在不修改原始逻辑的基础上对原始功能进行增强

无侵入,减少重复代码,提高开发效率,维护方便
定义类抽取公共代码
java 复制代码
@Aspect
标识AOP类,并且将这个类交给Spring容器管理
java 复制代码
@Component
配置公共代码作用的方法

@Around:环绕通知

在目标方法执行前后执行公共代码

任意 *

任意参数 ...

复制代码
执行目标方法
复制代码

使用动态代理实现AOP

当目标对象功能需要被增强时,并且我们使用AOP方式在Aspect类中定义了增强逻辑

Spring会为目标对象自动生成一个代理对象,并在代理对象对应方法中结合我们定义的AOP增强逻辑完成功能增强.

复制代码

AOP核心概念

连接点:JoinPoint(可以被AOP控制的方法执行)包含方法信息

通知:Advice,重复逻辑代码

切入点:PointCut,匹配连接点的条件(execution...)

切面:Aspect,通知+切点

AOP进阶

通知类型

java 复制代码
@Around
//此注解标注的通知方法在目标方法前后都执行
//需要自己调用ProceedingJoinPoint.proceed()方法来让目标方法执行
@Before
//此注解标注的通知方法在目标方法前被执行
@After
//此注解标注的通知方法在目标方法后被执行,无论是否存在异常
(在finally块中)
@AfterReturning
//同上,但有异常时不会执行,后于@After执行
@AfterThrowing
//在发生异常后执行

AOP通知顺序

当多个切面的切点都匹配目标时,多个通知方法都会被执行

默认按照类名字母排序
用@Order(数字)加在切面类上来控制顺序

目标前的通知方法:数字小先执行 升序

目标后的通知方法:数字大先执行 降序

顺序类似于进栈出栈

切点表达式

execution(返回值类型 包名 类名 方法名(参数类型))

...

@annotation()根据注解匹配

args()根据方法匹配

execution

根据方法的返回值,包名,类名,方法名,方法参数等信息来匹配

java 复制代码
execution(访问修饰符) 返回值 包名.类名.方法名(方法参数) throws 异常)

访问修饰符可省略

包名.类名可省略

throws异常:可省略(声明中抛出的异常而非方法实际抛出的异常)

annotation

切点表达式也支持匹配目标方法是否存在注解

使用@annotation

java 复制代码
@annotation(com.itheima.anno.Log)

@Pointcut

抽取一个切入点表达式,在其他地方通过类似调用的形式对其进行引用

java 复制代码
@Pointcut(切入点)
public void function()

@After("function()")

连接点

即目标方法,在Spring中使用JoinPoint抽象了连接点,用它可以获得方法执行时的相关信息,如方法名,方法参数类型,方法实际参数等.

对于@Around通知,获取连接点信息只能使用ProceedingJoinPoint

对应其他四种通知只能使用JoinPoint,即ProceedingJoinPoint的父类型

java 复制代码
//获取类名
getTarget().getClass().getName()
//获取方法名
getSignature().getName()
//获取参数(返回一个Object数组)
getArgs()

案例

java 复制代码
@Aspect
@Component
public class aspect {
    @Autowired
    LogMapper logMapper;

    @Autowired
    LoginControllerImpl loginController;

    @Around("execution(* com.example.tlias.service.Impl.*.*(..))")
    public Object caltime(ProceedingJoinPoint jp) throws Throwable{
        Logs logs = new Logs();
        Long start = System.currentTimeMillis();
        Object returns = jp.proceed();
        Long end = System.currentTimeMillis();
        System.out.println("时间" + (end - start));
        logs.setTime(end-start);
        logs.setFunctionName(jp.getSignature().getName());
        logs.setClassName(jp.getTarget().getClass().getName());
        logs.setReturns(JSONObject.toJSONString(returns));
        logs.setArgs(jp.getArgs().toString());
        logs.setUser(loginController.id);
        System.out.println("当前用户:" + logs.getUser());
        logs.setOpTime(LocalDateTime.now());
        logMapper.insert(logs);
        return returns;
    }


}
相关推荐
快乐就好ya1 小时前
Java多线程
java·开发语言
IT学长编程1 小时前
计算机毕业设计 二手图书交易系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·课程设计·毕业论文·计算机毕业设计选题·二手图书交易系统
CS_GaoMing2 小时前
Centos7 JDK 多版本管理与 Maven 构建问题和注意!
java·开发语言·maven·centos7·java多版本
艾伦~耶格尔2 小时前
Spring Boot 三层架构开发模式入门
java·spring boot·后端·架构·三层架构
man20172 小时前
基于spring boot的篮球论坛系统
java·spring boot·后端
2401_858120533 小时前
Spring Boot框架下的大学生就业招聘平台
java·开发语言
S hh3 小时前
【Linux】进程地址空间
java·linux·运维·服务器·学习
Java探秘者3 小时前
Maven下载、安装与环境配置详解:从零开始搭建高效Java开发环境
java·开发语言·数据库·spring boot·spring cloud·maven·idea
攸攸太上3 小时前
Spring Gateway学习
java·后端·学习·spring·微服务·gateway
2301_786964363 小时前
3、练习常用的HBase Shell命令+HBase 常用的Java API 及应用实例
java·大数据·数据库·分布式·hbase