当前位置: 首页 > article >正文

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

文章目录

一、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、使用

@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 前置通知,在我们的方法实际执行前调用

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

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

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

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

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

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

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

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

@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事务管理器
<!-- 配置 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事务管理对象的管理下执行

@Transactional
    public void save(){
        loginDao.insertAdmin1();
        System.out.println(10/0);
        loginDao.insertAdmin2();
    }

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

@Service (value = "loginService")
@Transactional
public class LoginService {
    @Autowired
    LoginDao 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.kler.cn/a/447773.html

相关文章:

  • 【Leecode】Leecode刷题之路第87天之扰乱字符串
  • C++版实用时间戳类(Timestamp)
  • Java并发编程框架之综合案例——在线聊天室(二)
  • 功能篇:JAVA8实现数据去重
  • Qt+OPC开发笔记(一):OPCUA介绍、open62541介绍、编译与基础环境Demo
  • K-Means 聚类:数据挖掘的瑞士军刀
  • 【期末复习】JavaEE(上)
  • powershell美化
  • 使用 Docker 打包和运行 Vue 应用
  • Suno Api V4模型无水印开发「人声伴奏分离」 —— 「Suno Api系列」第7篇
  • 成方金融科技后端部分笔试题 - 解析
  • Pytorch | 利用VMI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
  • Pytorch | 从零构建MobileNet对CIFAR10进行分类
  • 电子应用设计方案66:智能打印机系统设计
  • Vulkan 学习(11)---- Vulkan RenderPass 创建
  • Liunx下MySQL:表的约束
  • OpenTK 中帧缓存的深度解析与应用实践
  • Gemini 2.0:面向智能体时代的全新 AI 模型
  • 均值聚类算法
  • 【Jenkins】Declarative和Scripted两种脚本模式有什么具体的区别
  • 关于 node-sass 库在windows下编译错误
  • C#都可以找哪些工作?
  • 【机器人】机械臂轨迹和转矩控制对比
  • 语言学习大冒险:粤语、英语、西语的酸甜苦辣
  • 编写Linux系统rhel9的网络配置脚本
  • PYTHON 自动化办公:更改图片尺寸大小