【Spring】初阶三 - AOP

AOP

AOP是一种设计思想,面向切面编程,通过预编译方式和运行期动态代理方式实现在不修改源代码的情况下给程序动态添加额外功能的一种技术

代理模式

概念

将非核心逻辑剥离出来以后,封装这些非核心逻辑的类、对象、方法

静态代理

为某一个对象(委托类)提供一个代理(代理类),用来控制对这个对象的访问。委托类和代理类有一个共同的父类或父接口。代理类会对请求做预处理、过滤,将请求分配给指定对象。

类似找明星经纪人而不是直接去找明星

动态代理

JDK原生的实现方式,需要被代理的目标类必须实现接口

该技术要求代理对象和目标对象实现同样的接口

例子:

在这里插入图片描述

动态代理通过Proxy类调用newInstance方法生成某个对象的代理对象,其中使用到三个参数:

我们可以很明显的看到:

与静态代理不同的是,我们不需要自己编写代理类,这是动态生成的
在这里插入图片描述

基于注解的AOP

pom.xml添加依赖

<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.3.18</version>
</dependency>

配置文件添加标签

<aop:aspectj-autoproxy />

开启基于注解的AOP

通知

在切面中,需要通过指定的注解将方法表示为通知方法。

  • @Before:前置通知,在目标对象方法执行之前执行
  • @After:后置通知,在目标对象方法设为finally字句中执行
  • @AfterReturnning:返回通知,在目标对象方法返回值之后执行
  • @AfterThrowing:异常通知,在目标对象方法设为catch字句中执行
  • @Around:环绕通知

切面的优先级

通过@Order( value) 来设置优先级,value默认值是Integer的最大值,只要我们设置的数字比默认值小,它的优先级就比较高

声明式事务

声明式事务是建立在 AOP 之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况“提交”或者“回滚”事务。

编程式事务:

@Service
public class TransactionExample {

    /** 1、获取 PlatformTransactionManager 对象 **/
    @Autowired
    private PlatformTransactionManager platformTransactionManager;

    public void addUser() {
        // 2、获取默认事务定义
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        // 设置事务传播行为
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        // 3、根据事务定义对象设置的属性,获取事务状态
        TransactionStatus status = platformTransactionManager.getTransaction(def);
        try {
            // 4、执行业务代码(这里进行模拟,执行多个数据库操作方法)
            userMapper.delete(1);
            userMapper.delete(2);
            // 5、事务进行提交
            platformTransactionManager.commit(status);
        } catch(Exception e){
            // 5、事务进行回滚
            platformTransactionManager.rollback(status);
        }
    }

}

以前我们学的事务的管理分散在代码的四处,复用性不高。而且每一次都需要自己完成代码的编写

基于注解的声明式事务

配置事务管理器
<bean id="transactionManager"  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource"></property>    
</bean>
开启事务的注解驱动
<tx:annotation-driven transaction-manager="transactionManager"/>

在这里插入图片描述

使用@Transactional注解所标识的方法或类中所有的方法使用事务进行管理

transaction-manager属性设置事务管理器的id。当bean的id为transactionManager时也可以不设置。

小结:

声明式事务的配置步骤:

  1. 在Spring的配置文件中配置事务管理器

  2. 开启事务的注解驱动

在需要被事务管理的方法(或类)上,添加@Transactional注解,该方法就会被事务管理。

@Transactional注解标识的位置

  • 标识在方法上
  • 标识在类上,则类中所有的方法都会被事务管理

事务属性

只读、超时

只读属性 readonly && 事务超时属性 timeout

在这里插入图片描述

  • 只读属性表示该事务只读数据但是不更新数据,这可以防止脏读的发生
  • 超时属性表示事务在强制回滚前能够维持多长的时间。在这个时间内如果事务没有结束将强制结束。
回滚策略

在发生异常时,发生事务回滚。经了解,只有未检查异常可以导致事务回滚(RuntimeException和Error类型的异常),受检查异常不会。
在这里插入图片描述

隔离级别

隔离级别在学习数据库中已经提到:

在这里插入图片描述

在这里插入图片描述

上图源网络。

传播行为

有一个例子:

有一个人要买两本书,但是他的钱只能买一本。此时我们有两个业务:买书和结账。如果结账是一个事务的话,这个人的操作就会失败—一本书也买不到。但是我们明明可以先只买一本,此时就要求我们把买书看成一个事务。那么如何操作呢?

通过@Transactional中的propagation属性设置事务传播行为

在BookServiceImpl中的buyBook()上面,注解@Transactional的propagation属性

在这里插入图片描述

  • Propagation.REQUTRED:默认情况,如果当前线程上有已经开启的事务可用,那么就在这个事务中执行
  • Propagation.REQUTRES_NEW:表示不管当前线程上是否有已经开启的事务,都要开启新事务。这样,每次买书操作结束后都会开启新事务,这样就不会耦合性过高。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值