SpringBoot使用AOP进行自动化事务处理

  1. 什么是AOP
    AOP即面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
  2. AOP可以干什么
    利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性。
  3. AOP的常用注解
    SpringBoot使用AOP进行自动化事务处理_第1张图片
  4. 使用AOP进行SpringBoot事务控制
package com.xxxx.springboot;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.TransactionInterceptor;

@Aspect
@Component
public class SpringbootAop{

  /**
   * 注入事务管理器
   */
  @Autowired
  public PlatformTransactionManager platformTransactionManager;

  /**
   * 设置事务拦截器
   */
  @Bean
  public TransactionInterceptor transactionInterceptor(){
    // 设置事务属性,可以通过它设置事务的基本属性,如事务是读写事务或者只读事务,事务的超时时间等
    DefaultTransactionAttribute defaultTransactionAttribute = new DefaultTransactionAttribute();
    // 设置为读写事务
    defaultTransactionAttribute.setReadOnly(false);
    // 通过方法名匹配事务
    NameMatchTransactionAttributeSource nameMatchTransactionAttributeSource = new NameMatchTransactionAttributeSource();
    //所有类的save方法,不需要再添加 @Transactional注解,因为所有类的save方法都将被AOP统一拦截处理
    // 为 save 方法添加事务,事务属性为 defaultTransactionAttribute 设置的属性
    nameMatchTransactionAttributeSource.addTransactionalMethod("save", defaultTransactionAttribute);
    // 新建一个事务拦截器,使用 platformTransactionManager 作为事务管理器,拦截的方法为 nameMatchTransactionAttributeSource 中匹配到的方法
    return new TransactionInterceptor(platformTransactionManager, nameMatchTransactionAttributeSource);
  }


  @Bean
  public Advisor advisor(){
    AspectJExpressionPointcut aspectJExpressionPointcut = new AspectJExpressionPointcut();
    // execution 表达式,匹配 save 方法
    // 设置切点为com.xxx.springboot包下的所有方法名为save的方法
    aspectJExpressionPointcut.setExpression("execution(* com.xxx.springboot..*.save(..))");
    // 返回 aop 切面,切面 = 切点 + 通知
    return new DefaultPointcutAdvisor(aspectJExpressionPointcut, transactionInterceptor());
  }
}
  1. 在save方法里模拟异常,检验aop是否处理了事务
    调用以下方法时,会发现除0异常 被AOP拦截处理事务,导致插入的数据被回滚,即没有插入成功。
  public User save(User user) {
		// 保存实体类
        userRepository.save(user);
		// 人为抛出异常
        int xxaiui = 1 / 0;
        //修改密码
        user.setPassword("123456");
        //重新保存,更新记录
        return userRepository.save(user);
    }

你可能感兴趣的:(SpringBoot技术笔记,spring,aop,java)