java Sping aop 以及Spring aop 的应用事务管理

这篇具有很好参考价值的文章主要介绍了java Sping aop 以及Spring aop 的应用事务管理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 回顾

线程死锁概念和如何避免死锁的发生:

线程的通信 wait notify() notify():---Object类

线程的状态: NEW--->start()--->就绪状态---CPU时间片---运行状态RUNNABLE]--->sleep()--->TIMED_WAITING--->wait()---->WAITING----sysn---Blocked---->终止状态[T]

线程池: 常见的线程池种类: 4种和原始

2. 正文 (3W+1H what why where How)

1. 什么是AOP?
2. 为什么使用AOP?
3. 如何使用AOP?
4. 什么是事务?
5. spring如何实现事务管理。

3. 什么是AOP?

在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

AOP:它是面向切面编程的语言,它可以让你的业务代码和非业务代码进行隔离。在不改变业务代码的前提下,可以增加新的非业务代码。

4. 为什么使用AOP

5. AOP应用场景

  1. 记录日志
  2. 权限校验
  3. spring事务管理。

6. AOP的结构

AOP要做的三件事在哪里切入,也就是权限校验,等非业务操作在哪些业务 代码中执行;什么时候切入,是业务代码执行前还是执行后;切入后做什 么事,比如做权限校验、日志记录等。

  • Aspect: 切面
  • PointCut:切点:---方式: 路径表达式 (2)注解形式
  • Advice: 处理的时机。

7. 如何使用AOP

案例

public class MathServiceImpl implements MathService {
    public double add(double a, double b) {
        double result=a+b;
        System.out.println("AAA--->The add method result="+result);
        return result;
    }

    public double mul(double a, double b) {
        double result=a-b;
        System.out.println("AAA--->The mul method result="+result);
        return result;
    }

    public double cheng(double a, double b) {
        double result=a*b;
        System.out.println("AAA--->The cheng method result="+result);
        return result;
    }

    public double div(double a, double b) {
        double result=a/b;
        System.out.println("AAA--->The div method result="+result);
        return result;
    }
}

发现: 我们在每个操作后,都要记录日志,如果后期日志内容发生改变。需要在每个操作后都进行修改。 不利于代码的维护。

我们来使用AOP来解决。

(1)引入相关依赖

 <dependencies>
        <!--引入spring核心依赖库-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.12.RELEASE</version>
        </dependency>

        <!--引入spring切面依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.2.12.RELEASE</version>
        </dependency>
    </dependencies>

(2)创建一个切面类

@Aspect //标记该类为切面类
@Component //该类对象的创建交于spring容器来管理-----等价于@Service  @Controller
public class MyAspect {
    @Pointcut(value = "execution(public double com.ykq.aop.MathServiceImpl.add(double, double))")  //定义为切点
    private void mypointcut(){}

    @After(value = "mypointcut()")
    public void b(){
        System.out.println("AAA--->The add method result");
    }

}

(3) 创建一个spring配置文件

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--包扫描-->
    <context:component-scan base-package="com.ykq.aop"/>

    <!--开启aop切面注解驱动-->
    <aop:aspectj-autoproxy/>
</beans>

(4)测试

public class Test {
    public static void main(String[] args) {
        //加载spring配置文件
        ApplicationContext app=new ClassPathXmlApplicationContext("classpath:spring.xml");

        MathService mathServiceImpl = (MathService) app.getBean("mathServiceImpl");

        System.out.println(mathServiceImpl.add(20, 10));
    }
}

使用通配符来统配类路径

@Aspect //标记该类为切面类
@Component //该类对象的创建交于spring容器来管理-----等价于@Service  @Controller
public class MyAspect {
    //通配符:
    /**
     * 第一个* : 表示任意修饰符 任意返回类型。
     * 第二个* : 表示该包下所有的类。
     * 第三个* : 类下所有的方法
     * ..: 表示任意参数
     *
     * 建议包就别使用统配符
     */
    @Pointcut(value = "execution(* com.ykq.aop.*.*(..))")  //定义为切点
    private void mypointcut(){}

    @After(value = "mypointcut()")
    public void b(){
        System.out.println("AAA--->The add method result");
    }
}

7.2 注解模式

(1)自定义注解

@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value() default "";
}

(2)修改切面类


    @Pointcut(value = "@annotation(com.ykq.aop.MyAnnotation)")  //定义为切点
    private void mypointcut2(){}

    //在使用MyAnntation注解的方法之后执行内容
    @After(value = "mypointcut2()")
    public void b(){
        System.out.println("AAA--->The add method result");
    }

7.3 aop切面通知的类型

package com.aaa.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Aspect //标记该类为切面类
@Component //该类对象的创建交于spring容器来管理-----等价于@Service  @Controller
public class MyAspect {
    //通配符:
    /**
     * 第一个* : 表示任意修饰符 任意返回类型。
     * 第二个* : 表示该包下所有的类。
     * 第三个* : 类下所有的方法
     * ..: 表示任意参数
     *
     * 建议包就别使用统配符
     */
    @Pointcut(value = "execution(* com.ykq.aop.*.*(..))")  //定义为切点
    private void mypointcut(){}



    @Pointcut(value = "@annotation(com.ykq.aop.MyAnnotation)")  //定义为切点
    private void mypointcut2(){}



//    //在使用MyAnntation注解的方法之后执行内容。无论如何都执行。
//    @After(value = "mypointcut()")
//    public void a(){
//        System.out.println("AAA--->The add method result");
//    }
//
//    //前置通知:
//    @Before(value = "mypointcut()")
//    public void b(){
//        System.out.println("========方法执行前执行切面的内容  前置通知===========");
//    }
//
//    //后置返回通知. 碰到return. 如果方法出现异常;这种通知不会被执行
//    @AfterReturning(value = "mypointcut()",returning = "r")  //returnning它会把方法执行的结果赋值给该变量
//    public void afterReturning(Object r){ //参数名必须和returning的名称一致
//        System.out.println("~~~~~~~~~~~~~~~~~~后置返回通知~~~~~~~~~~~~~~~~"+r);
//    }
//
//    //异常通知: 当被切入的方法出现异常时,才会执行
//    @AfterThrowing(value = "mypointcut()")
//    public void afterThrowable(){
//        System.out.println("==============异常通知===========================");
//    }

    //环绕通知。
    @Around(value = "mypointcut()")
    public Object around(ProceedingJoinPoint joinPoint){//joinPoint:连接点  理解为被执行的方法对象
        System.out.println("业务代码执行前执行的内容======================");
        try {
            Object result = joinPoint.proceed();//执行你的连接点
            System.out.println("方法执行完毕后~~~~~~~~~~~~~~~~~");
            return result;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println("方法出现异常时执行~~~~~~~~~~~~~");
        }finally{
            System.out.println("无论如何都会执行");
        }
        return 0.0;
    }
}

@Before 前置通知. 被代理的方法执行前--执行

@After: 后置通知: 被代理的方法执行完后--执行

@AfterReturning: 后置返回通知: 被代理的方法碰到return.--才会执行

@AfterThrowing: 后置异常通知: 当被代理的方法出现异常时--才会执行。

@Around: 环绕通知。

8. spring如何操作事务

8.1 什么是事务?

事务就是一系列的动作, 它们被当做一个单独的工作单元. 这些动作要么全部完成, 要么全部不起作用.

例子: 转账

扣钱和加钱----要么都执行要么都不执行。

JDBC----它模式事务自动提交的。

public class Test {
    public static void main(String[] args) {
        Connection conn=null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/aaa?serverTimezone=Asia/Shanghai","root","root");
            conn.setAutoCommit(false);//设置事务手动提交。
            PreparedStatement ps=conn.prepareStatement("update t_user set balance=balance-600 where id=7");
            ps.executeUpdate();
            //int i=10/0;
            PreparedStatement ps2=conn.prepareStatement("update t_user set balance=balance+600 where id=6");
            ps2.executeUpdate();
            conn.commit();//事务提交
        }catch (Exception e){
            e.printStackTrace();
            //事务回滚
            try {
                conn.rollback();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }finally {

        }
    }
}

8.2 spring如何实现事务

spring框架一定会提供一个事务切面类。【1】前置通知---开启手动事务 [2]后置返回通知[事务提交] [3]异常通知[事务回滚]

(1)依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.12.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.2.12.RELEASE</version>
        </dependency>
        <!--spring事务依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.2.12.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.15.RELEASE</version>
        </dependency>

        <!--mybatis的依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.9</version>
        </dependency>
        <!--mybatis和spring整合的依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.7</version>
        </dependency>
        <!--druid的连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.28</version>
        </dependency>
    </dependencies>

(2)spring配置文件

<?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:mvc="http://www.springframework.org/schema/mvc" 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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--springmvc的配置-->
    <context:component-scan base-package="com.ddd"/>



    <!--spring整合mybatis的配置-->

    <!--数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
          <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
          <!--mysql驱动为8.0以后必须使用时区-->
          <property name="url" value="jdbc:mysql://localhost:3306/aaa?serverTimezone=Asia/Shanghai"/>
          <property name="username" value="root"/>
          <property name="password" value="root"/>
    </bean>

    <!--spring封装了一个类SqlSessionFactoryBean类,可以把mybatis中的配置-->
    <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
          <property name="dataSource" ref="dataSource"/>
          <property name="mapperLocations" value="classpath:/mapper/*.xml"/>
    </bean>

    <!--为指定dao包下的接口生产代理实现类-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sessionFactory"/>
        <!--它会为com.ykq.dao包下的所有接口生产代理实现类-->
        <property name="basePackage" value="com.ddd.dao"/>
    </bean>

<!----================以下内容是关于事务的配置===================------>
    <!--事务切面管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--开启事务管理注解的驱动-->
    <tx:annotation-driven/>
</beans>

(3) dao类和xml

public interface UserDao {
    //1.修改账号余额
    public void updateBalance(@Param("id") int id, @Param("money") double money);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace必须和dao接口的名称一模一样-->
<mapper namespace="com.ddd.dao.UserDao">
    <update id="updateBalance">
          update  t_user set balance=balance+#{money} where id=#{id}
    </update>
</mapper>

(4)service

package com.ddd.service.impl;

import com.ddd.dao.UserDao;
import com.ddd.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserServieImpl implements UserService {
    @Autowired
    private UserDao userDao;

    @Transactional //该方法交于spring的事务来管理了---默认spring不识别该注解
    public void zhuanzhang(int id, int uid, double money) {

        //1.扣钱
        userDao.updateBalance(id,-money);
        //int c=10/0;
        //2.收钱
        userDao.updateBalance(uid,money);
    }
}

(5)测试:文章来源地址https://www.toymoban.com/news/detail-652457.html

public class Test {
    public static void main(String[] args) {
        ApplicationContext app=new ClassPathXmlApplicationContext("classpath:spring.xml");
        UserService userServieImpl = (UserService) app.getBean("userServieImpl");
        userServieImpl.zhuanzhang(7,6,400);
    }
}

到了这里,关于java Sping aop 以及Spring aop 的应用事务管理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Spring使用@Transactional 管理事务,Java事务详解。

    B站视频:https://www.bilibili.com/video/BV1eV411u7cg 技术文档:https://d9bp4nr5ye.feishu.cn/wiki/HX50wdHFyiFoLrkfEAAcTBdinvh 简单来说事务就是一组对数据库的操作 要么都成功,要么都失败。 事务要保证可靠性,必须具备四个特性:ACID。 A:原子性:事务是一个原子操作单元,要么完全执行,要么

    2024年02月11日
    浏览(11)
  • [JavaWeb]【十二】web后端开发-事务管理&AOP

    [JavaWeb]【十二】web后端开发-事务管理&AOP

    目录 一、事务管理 1.1 事务回顾 1.2 Spring事务管理 1.2.1 案例  1.2.1.1 EmpMapper新增deleteByDeptId方法  1.2.1.2 DeptServiceImpl   1.2.1.3 启动服务-测试  1.2.2 模拟异常 1.2.3  分析问题  1.2.4 Spring事务管理(一般用在类似多次delete)  1.2.4.1 开启事务开关application.yml 1.2.4.2  DeptServiceImpl 

    2024年02月11日
    浏览(10)
  • Spring 事务管理方案和事务管理器及事务控制的API

    Spring 事务管理方案和事务管理器及事务控制的API

    目录 一、事务管理方案 1. 修改业务层代码 2. 测试 二、事务管理器 1. 简介 2. 在配置文件中引入约束 3. 进行事务配置 三、事务控制的API 1. PlatformTransactionManager接口 2. TransactionDefinition接口 3. TransactionStatus接口 往期专栏文章相关导读  1. Maven系列专栏文章 2. Mybatis系列专栏文

    2024年02月08日
    浏览(16)
  • 【Java学习】 Spring的基础理解 IOC、AOP以及事务

    【Java学习】 Spring的基础理解 IOC、AOP以及事务

        官网: https://spring.io/projects/spring-framework#overview     官方下载工具: https://repo.spring.io/release/org/springframework/spring/     github下载: https://github.com/spring-projects/spring-framework     maven依赖: 1.spring全家桶的结构构图:              最下边的是测试单元   其中spring封装

    2024年02月09日
    浏览(19)
  • spring事务管理详解和实例(事务传播机制、事务隔离级别)

    spring事务管理详解和实例(事务传播机制、事务隔离级别)

    目录 1 理解spring事务 2 核心接口 2.1 事务管理器 2.1.1 JDBC事务 2.1.2 Hibernate事务 2.1.3 Java持久化API事务(JPA) 2.2 基本事务属性的定义 2.2.1 传播行为 2.2.2 隔离级别 2.2.3 只读 2.2.4 事务超时 2.2.5 回滚规则 2.3 事务状态 3 编程式事务 3.1 编程式和声明式事务的区别 3.2 如何实现编程式

    2024年02月06日
    浏览(14)
  • 【Spring】Spring的事务管理

    【Spring】Spring的事务管理

    Spring的事务管理简化了传统的事务管理流程,并且在一定程度上减少了开发者的工作量。 1.1 事务管理的核心接口 在Spring的所有JAR包中包含一个名为Spring-tx-4.3.6.RELEASE的JAR包,该包就是Spring提供的用于事务管理的依赖包。在该JAR包的org.Springframework.transaction包中有3个接口文件:

    2024年02月03日
    浏览(16)
  • Spring 事务管理

    Spring 事务管理

    目录 1. 事务管理 1.1. Spring框架的事务支持模型的优势 1.1.1. 全局事务 1.1.2. 本地事务 1.1.3. Spring框架的一致化编程模型 1.2. 了解Spring框架的事务抽象(Transaction Abstraction) 1.2.1. Hibernate 事务设置 1.3. 用事务同步资源 1.3.1. 高级同步方式 1.3.2. 低级同步方式 1.3.3.TransactionAwareDataSo

    2024年02月13日
    浏览(14)
  • Spring的事务管理

    1、事务的回顾 【1】事务的定义 是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作,这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合 【2】事务的ACID原则 事务具有4个基本特性:原子性、一致性

    2023年04月16日
    浏览(19)
  • Spring之事务管理

    Spring之事务管理

    事务是数据库操作最基本单位,要么都成功,要么都失败。 原子性 一致性 隔离性 持久性。 Spring定义了7种传播行为: 传播属性 描述 REQUIRED 如果有事务在运行,当前的方法就在这个事务内运行,否则,就启动一个新的事务,并在自己的事务内运行 REQUIRED_NEW 当前的方法必须

    2024年02月13日
    浏览(15)
  • 【掌握Spring事务管理】深入理解事务传播机制的秘密

    【掌握Spring事务管理】深入理解事务传播机制的秘密

    🎉🎉🎉 点进来你就是我的人了 博主主页: 🙈🙈🙈 戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔 🤺🤺🤺 目录 1.Spring 中事务的实现方式 1.1 Spring 编程式事务 (了解) 1.2 Spring 声明式事务 ( @Transactional ) 【异常情况一】(自动回滚成功) 【异常情况二】(自动回滚失效

    2024年02月10日
    浏览(13)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包