SSM框架(二):AOP和事物

news2024/10/5 23:27:05

文章目录

  • 一、AOP的介绍
    • 1.1 基本概念
    • 1.2 AOP入门
    • 1.3 AOP工作流程
    • 1.4 切入点表达式
    • 1.5 AOP的通知类型
    • 1.6 ProceedingJoinPoint
    • 1.7 AOP通知获取参数数据
  • 二、事物
    • 2.1 基本介绍
    • 2.2 事物角色
    • 2.3 事物属性
    • 2.4 事物的传播行为


一、AOP的介绍

1.1 基本概念

在这里插入图片描述

在这里插入图片描述

1.2 AOP入门

  1. 导入坐标
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.10.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.4</version>
    </dependency>
  1. 定义dao接口和实现类
@Repository
public class BookDaoImpl implements BookDao {

    public void save() {
        System.out.println(System.currentTimeMillis());
        System.out.println("book dao save ...");
    }

    public void update(){
        System.out.println("book dao update ...");
    }
}
  1. 定义通知类:定义切入点,绑定切入点与通知的关系
//通知类必须配置成Spring管理的bean
@Component
//设置当前类为切面类类
@Aspect
public class MyAdvice {
    //设置切入点,要求配置在方法上方
    @Pointcut("execution(void com.itheima.dao.impl.BookDaoImpl.update())")
    private void pt(){}

    //设置在切入点pt()的前面运行当前操作(前置通知)
    @Before("pt()")
    public void method(){
        System.out.println(System.currentTimeMillis());
    }
}
  1. 开启Spring对AOP注解驱动的支持
@Configuration
@ComponentScan("com.itheima")
//开启注解开发AOP功能
@EnableAspectJAutoProxy
public class SpringConfig {
}

1.3 AOP工作流程

在这里插入图片描述
在这里插入图片描述

1.4 切入点表达式

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

1.5 AOP的通知类型

在这里插入图片描述

  1. @after:当前通知方法在原始切入点方法后运行
  2. @before:当前通知方法在原始切入点方法前运行
  3. @AfterReturning:当前通知方法在原始切入点方法正常执行完毕后执行
  4. @AfterThrowing:当前通知方法在原始切入点方法运行抛出异常后执行
  5. @Around:当前通知方法在原始切入点方法前后运行

在这里插入图片描述

演示:

@Component
@Aspect
public class MyAdvice {
    @Pointcut("execution(void com.itheima.dao.BookDao.update())")
    private void pt(){}
    @Pointcut("execution(int com.itheima.dao.BookDao.select())")
    private void pt2(){}

    //@Before:前置通知,在原始方法运行之前执行
//    @Before("pt()")
    public void before() {
        System.out.println("before advice ...");
    }

    //@After:后置通知,在原始方法运行之后执行
//    @After("pt2()")
    public void after() {
        System.out.println("after advice ...");
    }

    //@Around:环绕通知,在原始方法运行的前后执行
//    @Around("pt()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("around before advice ...");
        //表示对原始操作的调用
        Object ret = pjp.proceed();
        System.out.println("around after advice ...");
        return ret;
    }

//    @Around("pt2()")
    public Object aroundSelect(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("around before advice ...");
        //表示对原始操作的调用
        Integer ret = (Integer) pjp.proceed();
        System.out.println("around after advice ...");
        return ret;
    }

    //@AfterReturning:返回后通知,在原始方法执行完毕后运行,且原始方法执行过程中未出现异常现象
//    @AfterReturning("pt2()")
    public void afterReturning() {
        System.out.println("afterReturning advice ...");
    }

    //@AfterThrowing:抛出异常后通知,在原始方法执行过程中出现异常后运行
    @AfterThrowing("pt2()")
    public void afterThrowing() {
        System.out.println("afterThrowing advice ...");
    }
}

1.6 ProceedingJoinPoint

@Component
@Aspect
public class ProjectAdvice {
	//配置业务层的所有方法
	@Pointcut("execution(* com.itheima.service.*Service.*(..))")
	private void servicePt(){}
	//@Around("ProjectAdvice.servicePt()") 可以简写为下面的方式
	@Around("servicePt()")
	public void runSpeed(ProceedingJoinPoint pjp){
		//获取执行签名信息
		Signature signature = pjp.getSignature();
		//通过签名获取执行操作名称(接口名)
		String className = signature.getDeclaringTypeName();
		//通过签名获取执行操作名称(方法名)
		String methodName = signature.getName();
		long start = System.currentTimeMillis();
		for (int i = 0; i < 10000; i++) {
			pjp.proceed();
		}
		long end = System.currentTimeMillis();
		System.out.println("万次执行:"+ className+"."+methodName+"---->" +
		(end-start) + "ms");
	}
}

1.7 AOP通知获取参数数据

  1. 获取参数

在这里插入图片描述

  1. 获取返回值

在这里插入图片描述

  1. 获取异常

在这里插入图片描述

二、事物

2.1 基本介绍

在这里插入图片描述

  1. 在业务层接口的方法或者接口类(表示里面所有方法都事务管理)上添加事务管理注解@Transactional
public interface AccountService {
    /**
     * 转账操作
     * @param out 传出方
     * @param in 转入方
     * @param money 金额
     */
    //配置当前接口方法具有事务
    @Transactional
    public void transfer(String out,String in ,Double money) ;
}
  1. 设置事务管理器,创建一个事务管理的bean,例如:创建一个管理数据库的事物bean
public class JdbcConfig {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String userName;
    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }

    //配置事务管理器,mybatis使用的是jdbc事务
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource){
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
}
  1. 开启注解式事务驱动
@Configuration
@ComponentScan("com.itheima")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.class})
//开启注解式事务驱动
@EnableTransactionManagement
public class SpringConfig {
}

2.2 事物角色

在这里插入图片描述
在这里插入图片描述

2.3 事物属性

当代码抛出IOException异常时,事物不会回滚,因此我们需要设置@Transactional(rollbackFor={IOException.class})来保证遇到IO异常时事物回滚。

在这里插入图片描述

2.4 事物的传播行为

在这里插入图片描述

1.REQUIRES_NEW解读:
由于多个事物协调员由一个事物管理员管理,当一个事物失败时,其他事物也不能执行;当我们需要保证一个事物协调员不会受其他事物影响时,设置@Transactional(propagation=Propagation.REQUIRES_NEW)。

2.REQUIRES_NEW应用场景:
当我们在转账时,无论成功失败,都需要向数据库中写入日志,首先把转账与写日志写进一个转账Service的方法中,并加上事务管理@Transactional;然后我们就需要在日志的Service接口的方法中加入@Transactional(propagation=Propagation.REQUIRES_NEW)。

日志接口与实现类:LogService、LogServiceImpl

public interface LogService {
    //propagation设置事务属性:传播行为设置为当前操作需要新事务
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    void log(String out, String in, Double money);
}

@Service
public class LogServiceImpl implements LogService {

    @Autowired
    private LogDao logDao;

    public void log(String out,String in,Double money ) {
        logDao.log("转账操作由"+out+"到"+in+",金额:"+money);
    }
}

转账接口和实现类:AccountService、AccountServiceImpl

public interface AccountService {
    //rollback:设置当前事务参与回滚的异常,默认非运行时异常不参与回滚
//    @Transactional(rollbackFor = IOException.class)
    @Transactional
    public void transfer(String out,String in ,Double money) throws IOException;
}

@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;

    @Autowired
    private LogService logService;

    public void transfer(String out,String in ,Double money) {
        try{
            accountDao.outMoney(out,money);
            int i = 1/0;
            accountDao.inMoney(in,money);
        }finally {
            logService.log(out,in,money);
        }
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1234712.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数值计算方法】矩阵特征值与特征向量的计算(一):Jacobi 旋转法及其Python实现

文章目录 一、Jacobi 旋转法1. 基本思想2. 计算过程演示3. 注意事项 二、Python实现迭代过程&#xff08;调试&#xff09; 矩阵的特征值&#xff08;eigenvalue&#xff09;和特征向量&#xff08;eigenvector&#xff09;在很多应用中都具有重要的数学和物理意义。Jacobi 旋转…

Linux 环境配置小白入门

Linux从 全栈开发centOS 7 到 运维 一 Linux 入门概述1.1 操作系统1.2 Linux 简介1.3 Linux 系统组成1.4 Linux 发行版1.5 Linux 应用领域1.6 Linux vs Windows 二 虚拟机2.1 虚拟机介绍2.2 VMware WorkStation 安装2.3 VMware WorkStation 配置检查2.3 安装 CentOS 72.3.1 安装…

Git 远程仓库(Github)

目录 添加远程库 查看当前的远程库 提取远程仓库 推送到远程仓库 删除远程仓库 Git 并不像 SVN 那样有个中心服务器。 目前我们使用到的 Git 命令都是在本地执行&#xff0c;如果你想通过 Git 分享你的代码或者与其他开发人员合作。 你就需要将数据放到一台其他开发人员…

2021年03月 Scratch(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 小猫在沙漠中旅行好不容易找到了一杯水,初始位置如下图所示,下面哪个程序可以帮助它成功喝到水? A: B: C: D:

LR学习笔记——基本面板

文章目录 面板介绍色彩调整区域明暗调整区域纹理及质感色彩饱和 面板介绍 面板如上图所示 基本可分为几个板块&#xff1a;色彩、明暗、纹理及质感、色彩饱和 色彩调整区域 色温&#xff1a;由蓝色和黄色控制色调&#xff1a;由绿色和洋红控制 互补色&#xff1a;蓝色对黄色&…

opencv-形态学处理

通过阈值化分割可以得到二值图&#xff0c;但往往会出现图像中物体形态不完整&#xff0c;变的残缺&#xff0c;可以通过形态学处理&#xff0c;使其变得丰满&#xff0c;或者去除掉多余的像素。常用的形态学处理算法包括&#xff1a;腐蚀&#xff0c;膨胀&#xff0c;开运算&a…

Altium Designer学习笔记7

PCB封装库的制作&#xff1a; 距离的测量&#xff1a; 各个焊盘的位置&#xff1a; 直插元件选择Multi-Layer。如果贴片元件的则选择顶层Top-Layer&#xff0c;或者Bottom-Layer。 形状是方形&#xff0c;尺寸是2mm*2mm。 孔的尺寸是1.4mm。 则该器件就制作完成。 TSSOP28封装…

Java精品项目源码基于SpringBoot的樱花短视频平台(v66)

Java精品项目源码基于SpringBoot的樱花短视频平台(v66) 大家好&#xff0c;小辰今天给大家介绍一个樱花短视频平台&#xff0c;演示视频公众号&#xff08;小辰哥的Java&#xff09;对号查询观看即可 文章目录 Java精品项目源码基于SpringBoot的樱花短视频平台(v66)难度指数&…

Python3,必备数据可视化之:数据交互可视化

数据可视化之交互可视化 1、引言2、交互可视化介绍2.1 Bokeh2.1.1 基本定义2.1.2 常用功能2.1.3 安装2.1.4 代码示例 2.2 Plotly2.2.1 基本定义2.1.2 常用功能2.1.3 安装2.2.4 代码示例 2.3 Bokeh与Plotly 差异点 3、总结 1、引言 小屌丝&#xff1a;鱼哥&#xff0c;我发现一…

详解Python安装requests库的实例代码

文章目录 前言基本用法基本的get请求带参数的GET请求解析json关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料六、Python兼职渠道 前…

腾讯云COS+picgo+typora 图床搭建与自动上传

1、腾讯云 COS 腾讯云活动 COS新用户专享 COS 操作步骤 1、点击 创建桶&#xff0c;完善信息 点击下一步&#xff0c;剩下的配置可自己配置 2、picgo 官网地址 2.3.1版本下载地址 现在稳定版本是2.3.1 相关连接 腾讯云密钥设置地址picgo官网地址2.3.1版本下载地址

4-11 四个数排序

#include<stdio.h> int main(){int t,a,b,c,d;printf("请输入四个数&#xff1a;");scanf("%d %d %d %d",&a,&b,&c,&d);printf("a%d,b%d,c%d,d%d\n",a,b,c,d);if(a>b){ta;ab;bt;}if(a>c){ta;ac;ct;}if(a>d){ta;a…

注册亚马逊美国买家号需要些什么资料?

注册亚马逊美国买家号需要准备邮箱、美国手机号、美国地址及能支付的支付卡。准备好之后进入亚马逊美国站进行点击注册&#xff0c;按照格式填写好之后即可注册成功了。 而如果想要注册大量买家号&#xff0c;可以使用亚马逊鲲鹏系统进行自动化操作&#xff0c;想要自动化更顺畅…

【STM32】TF卡FTA32文件系统

一、SD卡介绍 1.SD简介 本质&#xff1a;NandFlash控制芯片 2.SD卡存储容量等级 3.FAT文件系统的使用 4.SD卡速度等级 5.SD卡驱动方式 1.SDIO&&SD 1&#xff09;SDIO接口通信线&#xff1a;CLK/CMD/DAT0-3&#xff08;数据传输线4根&#xff09; 2&#xff09;SPI接口…

这样做出来的电子杂志好看又精美,不信你也来试试!

大家会不会有一种困惑&#xff0c;为什么别人制作的电子杂志那么精美高级&#xff0c;能翻页&#xff0c;能分享到微信、微博等&#xff0c;而自己制作的电子杂志却是平平无奇&#xff1f; 在这个快节奏的时代&#xff0c;人们的生活方式也发生了翻天覆地的变化。而使用FLBOOK…

(swjtu西南交大)数据库实验(数据库需求分析):音乐软件数据管理系统

实验内容&#xff1a; 数据库需求分析&#xff1a;各用户组需求描述&#xff0c;绘出数据流图&#xff08;详细案例参见教材p333~p337&#xff0c;陶宏才&#xff0c;数据库原理及设计&#xff0c;第三版&#xff09;&#xff1b; 一、选题背景 近年来&#xff0c;“听歌”逐…

Python-函数传参与数据类型

Python中&#xff0c;函数参数传递是通过对象的引用进行的&#xff0c;我们可以进行下面的验证。 def use_name(val):print("name id :%s" % (id(val)))val "hanshu1"print("name id modified :%s" % (id(val)))def test_ref():name "ha…

CyNix

CyNix 一、主机发现和端口扫描 主机发现&#xff0c;靶机地址192.168.80.146 arp-scan -l端口扫描&#xff0c;只开放了80和6688端口 nmap -A -p- -sV 192.168.80.146二、信息收集 访问80端口 路径扫描 gobuster dir -u http://192.168.80.146/ -w /usr/share/wordlists/dir…

吴恩达《机器学习》9-4-9-6:实现注意:展开参数、梯度检验、随机初始化

一、实现注意:展开参数 在上一个视频中&#xff0c;讨论了使用反向传播算法计算代价函数的导数。在本视频中&#xff0c;将简要介绍一个实现细节&#xff0c;即如何将参数从矩阵展开为向量。这样做是为了在高级最优化步骤中更方便地使用这些参数。 二、梯度检验 在神经网络中…

如何制作动态表情包?一个方法快学起来

在当代的通讯工具中&#xff0c;动态表情包已经是人们日常交流不可缺少的一部分了。但是&#xff0c;很多时候网络上常见的动态表情包不能够很好表达出我们的需求时应该怎么办呢&#xff1f;这时候&#xff0c;我们可以使用gif动图制作&#xff08;https://www.gif.cn/&#xf…