Spring03--Spring基于注解的AOP、Spring事务

news2024/9/23 11:23:33

Spring基于注解的AOP

一、基于注解的AOP介绍

  • AOP注解方式 和 XML方式完成的功能是一样,只是采用方式不同而已。
  • 将原有的XML方式使用注解注意替代

二、环境搭建

  • 使用Spring02中Spring基于配置文件的AOP的环境搭建

三、使用注解替换XML的配置步骤

1、通知类使用注解和使用@Aspect注解声明为切面

在这里插入图片描述

2、在增强的方法上使用注解配置通知

(1)@Before

  • 作用:把当前方法看成是前置通知
  • 属性
    • value:用于指定切入点表达式,还可以指定切入点表达式的引用。
 @Before("execution(public void com.etime.service.impl.AccountServiceImpl.transferAccount(..))")
    public void startTransaction() {
        try {
            System.out.println("启动事务");
            connection.setAutoCommit(false);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }    

(2) @AfterReturning

  • 作用:把当前方法看成是后置通知。
  • 属性
    • value:用于指定切入点表达式,还可以指定切入点表达式的引用
    @AfterReturning("execution(public void com.etime.service.impl.AccountServiceImpl.transferAccount(..))")
    public void commitTransaction() {
        try {
            System.out.println("提交");
            connection.commit();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

(3)@AfterThrowing

  • 作用:把当前方法看成是异常通知。
  • 属性
    • value:用于指定切入点表达式,还可以指定切入点表达式的引用
    @AfterThrowing("execution(public void com.etime.service.impl.AccountServiceImpl.transferAccount(..))")
    public void rollbackTransaction() {
        try {
            System.out.println("回滚");
            connection.rollback();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

(4)@After

  • 作用:把当前方法看成是最终通知。
  • 属性
    • value:用于指定切入点表达式,还可以指定切入点表达式的引用
    @After("execution(public void com.etime.service.impl.AccountServiceImpl.transferAccount(..))")
    public void closeConnection() {
        try {
            System.out.println("释放资源");
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

3、在Spring 配置文件中开启 Spring 对注解AOP的支持

<!-- 开启 spring 对注解 AOP 的支持 -->
<aop:aspectj-autoproxy/>
  • 或者使用 在Spring 配置类中 使用注解@EnableAspectJAutoProxy开启对 注解AOP 的支持

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h8vxQISn-1683722293179)(F:\Java语言\课程笔记\第六阶段\myself\Spring\img\使用注解开启对注解AOP的支持.png)]

4、环绕通知直接配置

  • @Around
  • 作用:把当前方法看成是环绕通知。
  • 属性
    • value:用于指定切入点表达式,还可以指定切入点表达式的引用。
    @Around("execution(public void com.etime.service.impl.AccountServiceImpl.transferAccount(..))")
    public Object transactionAround(ProceedingJoinPoint pjp) {
        Object result = null;
        try {
            Object[] args = pjp.getArgs();
            startTransaction();
            result = pjp.proceed(args);
            commitTransaction();
        } catch (Throwable throwable) {
            rollbackTransaction();
            throwable.printStackTrace();
        } finally {
            closeConnection();
        }
        return result;
    }

5、切入点表达式注解

在这里插入图片描述

Spring事务讲解

1、Spring中事务的API详解

(1)PlatformTransactionManager作用

  • PlatformTransactionManager是一个 接口
  • 它是 Spring 的事务管理器,它里面提供了我们常用的操作事务的方法。

在这里插入图片描述

**注意:**PlatformTransactionManager 是接口类型,不同的 Dao 层技术则有不同的实现类,

  • Dao 层技术是jdbc 或 mybatis 时:org.springframework.jdbc.datasource.DataSourceTransactionManager

  • Dao 层技术是hibernate时:org.springframework.orm.hibernate5.HibernateTransactionManager

(2)TransactionDefinition作用

TransactionDefinition 是事务的定义信息对象,里面有如下方法

在这里插入图片描述

事务隔离级别

设置隔离级别,可以解决事务并发产生的问题,如脏读、不可重复读和虚读。

事务隔离级别说明
ISOLATION_DEFAULT默认级别,归属下列某一种
ISOLATION_READ_UNCOMMITTED未提交读,可以读取未提交数据
ISOLATION_READ_COMMITTED已提交读,只能读取已提交数据,解决脏读问题(Oracle默认级别)
ISOLATION_REPEATABLE_READ可重复读,解决不可重复度问题(MySQL默认级别)
ISOLATION_SERIALIZABLE串行化,解决幻读(虚读)问题
事务传播行为
事务传播行为说明
REQUIRED如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。一般的选择(默认值)
SUPPORTS支持当前事务,如果当前没有事务,就以非事务方式执行(没有事务)
MANDATORY使用当前的事务,如果当前没有事务,就抛出异常
REQUERS_NEW新建事务,如果当前在事务中,把当前事务挂起。
NOT_SUPPORTED以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
NEVER以非事务方式运行,如果当前存在事务,抛出异常
NESTED如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行 REQUIRED 类似的操作
事务超时时间

默认值是-1,没有超时限制。如果有,以秒为单位进行设置。

是否是只读事务

建议查询时设置为只读。

(3)TransactionStatus作用

TransactionStatus 接口提供的是事务具体的运行状态,方法介绍如下。
在这里插入图片描述

真正干活: 事务管理器 会根据TransactionDefinition 定义的信息, 进行事务的管理。管理过程当中产生事务的状态保存在TransactionStatus当中。

2、环境搭建

沿用上一小章节的代码,修改AccountDaoImpl 具体使用使用Spring提供的JdbcTemplate模板对象实现

package com.etime.dao.impl;

import com.etime.dao.AccountDao;
import com.etime.entity.Account;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public Account getAccountByName(String name){
        Account account = null;
        String sql = "select * from account where name = ?";
        account = jdbcTemplate.queryForObject( sql, new BeanPropertyRowMapper<>(Account.class),name);
        return account;
    }

    public int update(Account account){
        int rows = 0;
        String sql = "update account set money = ? where id = ?";
        rows = jdbcTemplate.update(sql, account.getMoney(), account.getId());
        return rows;
    }
}

3、事务管理配置步骤

(1)配置事务管理器

    <bean id="dtm" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="ds"></property>
    </bean>

(2) 配置事务的通知引用事务管理器

<!--事务的配置-->
    <tx:advice id="d" transaction-manager="dtm">

    </tx:advice>

(3)在tx:advice中配置事务的属性

<!-- 
    指定方法名称:是业务核心方法
     read-only:是否是只读事务。默认 false,不只读。
     isolation:指定事务的隔离级别。默认值是使用数据库的默认隔离级别。
     propagation:指定事务的传播行为。
     timeout:指定超时时间。默认值为:-1。永不超时。
     rollback-for:用于指定一个异常,当执行产生该异常时,事务回滚。产生其他异常,事务不回滚。
     没有默认值,任何异常都回滚。
     no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时,事务回滚。没有默认值,任何异常都回滚。
 -->
        <tx:attributes>
            <tx:method name="*"/>
        </tx:attributes>

(4)配置 AOP 切入点表达式

<!--事务的aop增强-->
    <aop:config>
        <aop:pointcut id="point"
                      expression="execution(public void com.etime.service.impl.AccountServiceImpl.transferAccount(..))"/>
    </aop:config>
<!--在aop:config标签内部:建立事务的通知和切入点表达式的关系-->
<aop:advisor advice-ref="d" pointcut-ref="point"></aop:advisor>

完整的配置文件内容:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd">

    <context:component-scan base-package="com.etime"></context:component-scan>
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    <bean id="ds" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <bean id="jt" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="ds"></property>
    </bean>

    <bean id="dtm" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="ds"></property>
    </bean>

    <tx:advice id="d" transaction-manager="dtm">
        <tx:attributes>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:pointcut id="point"
                      expression="execution(public void com.etime.service.impl.AccountServiceImpl.transferAccount(..))"/>
        <aop:advisor advice-ref="d" pointcut-ref="point"></aop:advisor>
    </aop:config>

</beans>

(5)测试

package com.etime.test;

import com.etime.service.AccountService;
import com.etime.util.SpringConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.sql.SQLException;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:application.xml"})
public class SpringTest {

    @Autowired
    private ApplicationContext context;

    @Test
    public void t01() throws SQLException {
        AccountService accountService = (AccountService) context.getBean("accountService");
        accountService.transferAccount("liudh", "fanbb" , 1000);
    }
}

iguration(locations = {“classpath:application.xml”})
public class SpringTest {

@Autowired
private ApplicationContext context;

@Test
public void t01() throws SQLException {
    AccountService accountService = (AccountService) context.getBean("accountService");
    accountService.transferAccount("liudh", "fanbb" , 1000);
}

}


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

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

相关文章

边缘化你必须知道的一件事!(FEJ知识点总结)

vins和g2o边缘化的异同&#xff1a;(已经做到ppt里面了&#xff0c;简单回顾一下) 1.《视觉slam14讲》中提及的边缘化(G2O边缘化)是在计算求解过程中&#xff0c;先消去路标点变量&#xff0c;实现先求解相机位姿&#xff0c;然后再利用求解出来的相机位姿反过来计算路标点的过…

qt creator添加build步骤删除某个文件

参考&#xff1a;https://blog.csdn.net/weixin_44436546/article/details/113587115 1. windows下配置&#xff1a; 添加build步骤&#xff1b;在commad栏输入cmd,会弹出C:\Windows\system32\cmd.exe&#xff1b;在Arguments栏输入/c release\upgrade.o&#xff1b;Working …

【数据结构】C语言实现双向链表(带头结点、循环)

C语言实现双向链表&#xff08;带头结点、循环&#xff09; 一、带头结点的循环双向链表二、结点与接口定义三、实现3.1 申请节点3.2 初始化3.3 打印3.4 尾插3.5 头插3.6 尾删3.7 判断链表为空断言3.8 头删3.9 查找find3.10 插入insert-在pos之前插入3.11 头插尾插复用insert3.…

机器学习算法实战(scikit-learn版本)---线性回归

目录 文章目标&#xff1a; 1&#xff0c;导入库 2&#xff0c;导入数据集 3&#xff0c;缩放/归一化训练数据 4,创建并拟合回归模型 5,查看参数 6,预测 7&#xff0c;可视化 有一个开源的、商业上可用的机器学习工具包&#xff0c;叫做[scikit-learn](https://scik…

阿里、京东等大厂年薪50w的测试都是什么水平?

各位做测试的朋友&#xff0c;但凡经历过几次面试&#xff0c;那么你一定曾被问到过以下问题&#xff1a; 1、在Linux环境下&#xff0c;怎么执行web自动化测试&#xff1f; 2、Shell如何&#xff0c;Docker熟悉吗&#xff1f; 3、全链路的压测实操过吗&#xff0c;如何推进与开…

【Linux】基本权限

&#x1f601;作者&#xff1a;日出等日落 &#x1f514;专栏&#xff1a;Linux 任何值得到达的地方&#xff0c;都没有捷径。 目录 Linux权限: 权限的概念&#xff1a; Linux上面的用户分类&#xff1a; Linux权限管理 文件访问者的分类&#xff08;人&#xff09; 文件…

小心白蛇!PyPI仓库被持续投放White Snake后门组件

背景 墨菲安全实验室在持续监测开源软件仓库中的投毒行为&#xff0c;4 月 14 日起陆续发现至少 41 个包含白蛇&#xff08;White Snake&#xff09;后门的 Python 包被发布到 PyPI 仓库&#xff0c;目前相关的后门包仍在持续发布。 事件简述 白蛇 &#xff08;WhiteSnake&a…

三种方法教你让模糊照片秒变高清图

现在随着数字相机和智能手机的普及&#xff0c;我们拍摄的照片数量越来越多&#xff0c;但是有些照片可能因为环境或技术等原因导致模糊不清&#xff0c;这时候我们就需要使用一些软件或工具来让照片变得清晰&#xff0c;以满足我们的需求。 下面介绍三种常用的照片变清晰的方…

专科生学习云计算的就业前景如何?

作为专科学历学习云计算&#xff0c;就业前景肯定是有的。因为目前开设云计算这门专业主要也是专科院校&#xff0c;目前入行的学历要求也是专科为起点&#xff0c;更加侧重技术技能水平&#xff0c;技术过关了才能找到合适的工作。 云计算作为一种新兴的IT技术方向&#xff0…

AI别来搅局,chatGPT的世界不懂低代码

ChatGPT单月访问量再创新高 根据SimilarWeb统计&#xff0c;ChatGPT上月全球访问量17.6亿次&#xff0c;已超越必应、鸭鸭走DuckDuckGo等其他国际搜索引擎&#xff0c;并达到谷歌的2%&#xff0c;百度的60%。 这会&#xff0c;程序员失业的段子又得再来一遍了&#xff1a; 拖…

Qt+WebRTC学习笔记(七)ubuntu22.04下搭建coturn(STUN/TURN)

前言 因工作原因&#xff0c;很长时间没更新相关文档了&#xff0c;笔者之前测试时&#xff0c;一直使用示例自带的公网中转服务器。考虑到后期项目需要&#xff0c;笔者在线搭建一个coturn服务器测试&#xff0c;供有需要的小伙伴使用 一、安装coturn 若需要最新版本的cotu…

Linux修改文件权限

目录 1、常用操作 2、文件属性 3、chmod命令详解 1.修改文件属主,也可以修改文件属组 2.修改文件权限 4.chgrp命令详解 1、常用操作 查看权限操作命令:# ls -l 在 Linux 中我们通常使用以下两个命令来修改文件或目录的所属用户与权限&#xff1a; chown (change ownerp)…

[python] Python类型提示指北

Python3.5 版本引入了类型提示&#xff08;Type Hints&#xff09;&#xff0c;它允许开发者在代码中显式地声明变量、函数、方法等的类型信息。这种类型声明不会影响 Python 解释器的运行&#xff0c;但可以让 IDE 和静态分析工具更好地理解代码&#xff0c;同时提高代码的可读…

《Netty》从零开始学netty源码(五十六)之MessageSizeEstimator

MessageSizeEstimator 在channel的配置类中有一个属性msgSizeEstimator&#xff0c;它的功能就是用来预估消息的大小&#xff0c;它的赋值过程如下&#xff1a; 接口MessageSizeEstimator只有一个方法newHandle()&#xff0c;它返回的接口handle是MessageSizeEstimator的内部类…

SpringBoot基础篇1(搭建环境+基础配置)

一、SpingBoot入门案例 SpringBoot是用来简化Spring应用的初始搭建以及开发过程。 先快速搭建一个SpringBoot&#xff1a; 创建一个空project&#xff0c;再创建SpringBoot模块。 点击Create&#xff0c;出现以下页面配置成功 创建一个控制器测试一下&#xff1a; RestCo…

Centos8搭建SMB服务

这里以Centos8为例&#xff0c;搭建简易的SMB服务。虚拟机配置&#xff1a;内存8G、存储64G、CPU单核四线程、网络NAT模式跳过虚拟机与系统配置部分&#xff0c;不清楚虚拟机配置以及创建的请查阅其他文档此文章只用于练习用&#xff0c;商业和个人用可以见解Truenas系统 更新…

改进YOLOv5 | C3模块改动篇 | 轻量化设计 |骨干引入高效卷积运算 DSConv: Efficient Convolution Operator

论文地址:https://arxiv.org/pdf/1901.01928v1.pdf 引入了一种卷积层的变体,称为DSConv(分布偏移卷积),其可以容易地替换进标准神经网络体系结构并且实现较低的存储器使用和较高的计算速度。 DSConv将传统的卷积内核分解为两个组件:可变量化内核(VQK)和分布偏移。 通过…

C 高级 /Day 2

#include<stdio.h> int Max_arr(int (*arr)[5],int row,int hang) {int max0;//最大值int k1;//循环行for(int i0;i<hang;i){int k1;//循环列for(int j0;j<row;j){//控制行和列for(int m0;m<hang;m){for(int n0;n<row;n){//如果是第m行的其他的元素&#xf…

MySQL原理(一):逻辑存储结构

前言 从本文开始&#xff0c;我将分享一下近期学习 MySQL 的笔记&#xff0c;其中大部分来源于极客时间的《MySQL实战45讲》、小林coding、以及部分其他博客和书籍。 这次系列文章着重讲 MySQL 的原理部分&#xff0c;主要是用于面试&#xff0c;也就是我们常说的八股&#x…

华为OD机试 - 有效的括号(Java)

一、题目描述 给定一个只包括 ‘(’&#xff0c;‘)’&#xff0c;‘{’&#xff0c;‘}’&#xff0c;‘[’&#xff0c;‘]’ 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。…