Spring AOP详解+事物解析

目录

Spring AOP定义:

Spring AOP的实现原理:

Spring AOP 支持以下常见的切面功能:

 Spring 事务的传播级别:

创建一个事物步骤:

1、首先,导入相关依赖(以下依赖是整合了ssm的所有依赖,所以可以直接复制使用)

2、引入 Spring 事务相关依赖后,在 Spring MVC 中有两种(XML 配置和注解)驱动 Spring 事务的方式

        a、接下来,我们先使用xml格式来配置事物

3、接着,你可以使用 @Transactional 注解标注在方法(或者类)上面,使得方法的执行处于一个事务中


Spring AOP定义:

        Spring AOP(Aspect-Oriented Programming)是Spring框架提供的一种面向切面编程的解决方案。AOP是一种编程范式,它可以从横向的切面来组织和管理程序逻辑,从而实现代码的重用和复合性的提高。Spring AOP通过在运行时动态地将切面织入到程序中,实现了对代码的横向切面管理,提高了代码的可重用性、可维护性和可扩展性。

Spring AOP的实现原理:

  • 切面(Aspect): 切面是一个横切关注点的模块化单元,它包含了通知和切点。通知是在切点上执行的代码,用于实现横切关注点的功能,如日志记录、性能监控等。切点是指在应用程序中定义的一组连接点,通知将在这些连接点上执行。
  • 代理: Spring AOP使用代理来实现切面功能。当一个Bean被代理时,Spring创建一个代理对象,该对象拦截了Bean的方法调用,并在方法调用前后执行通知。
  • 织入(Weaving): 织入是将切面与应用程序的目标对象关联起来的过程。Spring支持编译时织入、运行时织入和加载时织入三种织入方式。
  • 通知类型: Spring AOP支持五种通知类型:前置通知(Before)、后置通知(After)、返回通知(AfterReturning)、异常通知(AfterThrowing)和环绕通知(Around)。每种通知类型在不同的切点执行时机触发。
  • 实现原理: Spring AOP的实现原理主要基于动态代理和字节码增强。Spring使用动态代理来创建代理对象,并使用字节码增强技术在运行时修改类的字节码,以实现切面功能。具体实现方式包括JDK动态代理和CGLIB动态代理两种。

Spring AOP 支持以下常见的切面功能:

  • 前置通知(Before advice):在目标方法调用之前执行的操作。

  • 后置通知(After advice):在目标方法调用之后执行的操作,无论是否发生异常。

  • 返回通知(After returning advice):在目标方法成功返回结果后执行的操作。
  • 异常通知(After throwing advice):在目标方法抛出异常后执行的操作。

  • 环绕通知(Around advice):包围目标方法调用,可以在调用前后执行自定义操作(需要进行返回)

 Spring 事务的传播级别:

  • REQUIRED:默认传播级别,如果正处于一个事务中,则加入;否则,创建一个事务
  • SUPPORTS:如果正处于一个事务中,则加入;否则,不使用事务
  • MANDATORY:如果当前正处于一个事务中,则加入;否则,抛出异常
  • REQUIRES_NEW:无论如何都会创建一个新的事务,如果正处于一个事务中,会先挂起,然后创建
  • NOT_SUPPORTED:不使用事务,如果正处于一个事务中,则挂起,不使用事务
  • NEVER:不使用事务,如果正处于一个事务中,则抛出异常
  • NESTED:嵌套事务,如果正处于一个事务中,则创建一个事务嵌套在其中(MySQL 采用 SAVEPOINT 保护点实现的);否则,创建一个事务

创建一个事物步骤:

1、首先,导入相关依赖(以下依赖是整合了ssm的所有依赖,所以可以直接复制使用)
 <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.10.RELEASE</version>
    </dependency>
    <!--文件下载-->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.4</version>
    </dependency>

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

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>5.2.10.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.6</version>
    </dependency>

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.0</version>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.30</version>
    </dependency>

    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.16</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
2、引入 Spring 事务相关依赖后,在 Spring MVC 中有两种(XML 配置和注解)驱动 Spring 事务的方式
        a、接下来,我们先使用xml格式来配置事物
<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <!-- 定义一个数据源 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">...</bean>
    <!-- 事务管理器 -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 指定数据源 -->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!-- 事务模块驱动,指定使用上面定义事务管理器,默认值为 transactionManager -->
    <tx:annotation-driven transaction-manager="txManager"/>
</beans>

b、使用配置类的方式,需要在 Spring 能扫描的一个 Bean 上添加一个@EnableTransactionManagement 注解,然后添加一个事物类,并在spring配置当中使用Import注解导入配置类

文件部分结构:(将JdbcConfig文件使用注解的方式配置在SpringConfig中)

package com.yinan.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

public class JdbcConfig {

    private String username="root";

    private final String password="123456";
    private final String url="jdbc:mysql://localhost:3306/product";

    private final String driver="com.mysql.cj.jdbc.Driver";
    @Bean
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driver);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }
//    添加事物
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
}
package com.yinan.config;


import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.transaction.annotation.EnableTransactionManagement;


//配置spring  
@Configuration

@ComponentScan(value="com.yinan.service")
@Import({JdbcConfig.class, MybatisConfig.class})
@EnableTransactionManagement
public class SpringConfig {
}
3、接着,你可以使用 @Transactional 注解标注在方法(或者类)上面,使得方法的执行处于一个事务中
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
public void update(){
    try {
        // 数据库操作
    } catch (Exeception e){
        // 将事务状态设置为回滚
        TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

银氨溶液

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值