Spring——IOC、AOP、7种事务传播

1.IOC

在这里插入图片描述

1.什么是控制反转?

  • 就是把创建和管理bean的过程交给第三方,而这个第三方就是IoC容器。
  • 容器负责创建、配置和管理bean,也就是管理着bean的生命,控制着bean的依赖注入。
1. 为什么要用 IoC 这种思想呢?

答:解藕。
在这里插入图片描述
在这里插入图片描述

  • 本来ABCD是互相关联在一起的,当加入第三方容器的管理后,每个对象都和第三方Ioc容器相互关联,ABCD彼此不再联系,解除了耦合关系,全由容器来实现。
2. 什么是bean?——包装好了的Object
  • Bean其实就是包装了的Object,无论是控制反转,还是依赖注入,它的主语都是Object,而Bean就是第三方包装好了的Object。(别人送(Ioc容器)你礼物的时候要包装一下,自己造(自己new对象)的就避免了)。
  • Bean是Spring的主角,有种说法叫做Spring就是面向Bean的编程。
3.Bean的生命周期是什么?

在这里插入图片描述

  • 1.Spring对Bean进行实例化(相当于程序中的new);

  • 2.Spring将值、Bean的引用注入到Bean对应的属性中;

  • 3.如果Bean是实现了BeanNameAware接口,Spring将Bean的ID传递给setBeanName()方法;(实现BeanNameAware接口,主要是为了通过Bean的引用来获得Bean的ID,一般业务中是很少使用到Bean的ID的)

  • 4.如果Bean是实现了BeanFactoryAware接口,Spring将调用setBeanFactory(BeanFactory bf对象)方法,并把BeanFactory容器实例作为参数传入。(实现BeanFactoryAware主要目的是为了获取Spring容器,如,Bean通过Spring容器发布事件等)

  • 5.如果Bean实现了ApplicationContextAware接口,Spring容器将调用setApplicationContext(ApplicationContext ctx对象)方法,把应用上下文作为参数传入。(作用与BeanFactory类似都是为了获取Spring容器,不同的是Spring容器在调用setApplicationContext方法时会把它自己作为 setApplicationContext的参数传入,而Spring容器在调用setBeanDactory前需要程序员自己指定(注入)setBeanDactory里的参数BeanFactory)

  • 6.如果发现Bean实现了BeanPostPeocess接口,Spring将调用它们的postProcessBeforeInitialization(预初始化)方法。(作用是在Bean实例创建后对其进行增强处理,如,对Bean进行修改,增加某个功能)

  • 7.如果Bean实现了InitializingBean接口,Spring将调用它的afterPropertiesSet方法,作用与在配置文件中对Bean使用init-method生命初始化的作用一样,都是在Bean的全部属性设置成功后进行初始化的方法。

  • 8.如果Bean实现了BeanPostProcess接口,Spring将调用它们的postProcessAfterInitialization(后初始化)方法(作用与6的一样,只不过6是在Bean初始化前执行的,而这个是在Bean初始化后执行的,时机不同 )

  • 9.经过以上的工作后,Bean将一直驻留应用上下文中给应用使用,直到应用上下文被销毁。

  • 10如果Bean实现了DispostbleBean接口,Spring将调用它的destory方法,作用与在配置文件中对Bean使用destory-method属性的作用一样,都是在Bean实例销毁前执行的方法

4.应用上下文什么时候销毁?

实际上refresh执行完成后Spring应用上下文从广义上来说已经启动了,start回调用LifeCycleProcessors的start方法,可以理解refresh处理Spring应用上下文启动需要的东西,start相当于是一个扩展,close和stop是和refresh和close类似的逆向操作。123456

2.IoC容器

1.什么是BeanFactory?

简单粗暴理解为是HashMap:

  • Key——bean id
  • Value —bean object
    一般只有get、put这两个方法,所以是低级容器
2.什么是ApplicationContext?

1.它是BeanFactory的子类,他继承了很多的接口,多了很多功能,所以是高级容器
2.他有2个具体的实现子类,用来读取配置文件

  • ClassPathXmlApplicationContext——从classpath加载文件,更常用一些。
  • FileSystemXmlApplicationContext - 从本地文件中加载配置文件,不是很常用

3.深入理解IoC?

举例如下:

  • 2个变量:长、宽
  • 自动生成:set()方法、toString()方法
注意:
  • set()方法是必须的,因为Spring容器是通过set方法注入的。
public class Rectangle {
    private int width;
    private int length;

    public Rectangle() {
        System.out.println("Hello World!");
    }

    public void setWidth(int widTth) {
        this.width = widTth;
    }

    public void setLength(int length) {
        this.length = length;
    }

    @Override
    public String toString() {
        return "Rectangle{" +
                "width=" + width +
                ", length=" + length +
                '}';
    }
}

4.几个关键问题

1.何为控制?控制的是什么?
  • bean的创建、管理的权利就是控制。
  • 控制的是bean的整个生命周期 。
2.什么是反转?反转了什么?
  • 反转: 这个权力交给了Spring容器,而不是自己去控制,这就是反转;
  • 由之前的自己主动创建对象,变成,被动接收别人给我们的对象的过程,就是反转。

5.依赖注入——IoC is also known as DI

  • IOC是一种思想,DI是他的具体实现。控制反转是通过依赖注入实现的。
1.何为依赖?依赖什么?

程序运行需要依赖外部的资源,来提供程序内对象所需的数据、资源。
比方说:

  • 给对象的属性赋值
2.何为注入?注入什么?

配置文件把资源从外部注入到内部,容器加载了外部的文件、对象、数据,然后把这些资源注入给程序内的对象,维护了程序内外对象之间的依赖关系

2.AOP

1.什么是AoP

  • Aop是面向切面编程。能在不影响原有功能的前提下,为软件横向扩展功能。
  • 利用Aop可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性。提升开发效率。
  • 公共业务(日志、安全(校验参数))和领域业务(add、sub等等),当执行领域业务时,将会把公共业务结合起来,实现公共业务的重复利用,领域业务更纯粹,让程序员专注于领域业务,本质还是动态代理
AOP前后对比

3.Spring的事务传播行为?

1.什么是事务?

ACID特性

2.并发事务导致的问题

在许多事务处理同一个数据时,如果没有采取有效的隔离机制,那么并发处理数据时,会带来一些的问题。

3.Spring的事务传播

事务传播行为:用来描述由某一个事务传播行为修饰的方法,被嵌套进另一个方法时如何传播?

  • 如下:被事务修饰的methodB被嵌套进methodA
public void methodA(){
    methodB();
 }

 @Transaction(Propagation=XXX)
 public void methodB(){
 }

事务的7种传播行为

在这里插入图片描述

在这里插入图片描述

代码验证

下文的代码以传统三层结构中的两层呈现,即Service层、Dao层,由Spring负责依赖注入注解式事务管理,DAO层由Mybatis实现,数据库使用MySql。

1.首先创建2张表

在这里插入图片描述

2.然后编写相应的Bean和Dao层代码
1.User1的Bean

在这里插入图片描述

2. User1的DAO层

在这里插入图片描述

3.User1的DAO层

在这里插入图片描述

4.User2的Bean

在这里插入图片描述

最后也是具体验证的代码由 service 层实现,下面我们分情况列举。
1.Propagation.REQUIRED

在这里插入图片描述

我们为 User1Service 和 User2Service 相应方法加上Propagation.REQUIRED属性。

在这里插入图片描述

1.1. 场景1——此场景外围方法没有开启事务

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

1.2.场景2

外围方法开启事务,这个是使用率比较高的场景。——一荣俱荣、一损俱损
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.Propagation.NESTED

在这里插入图片描述

我们为 User1Service 和 User2Service 相应方法加上Propagation.NESTED属性。
X

2.1 场景一

此场景外围方法没有开启事务。
在这里插入图片描述
在这里插入图片描述

2.2.场景二——外围方法开启事务。

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

3.Propagation.REQUIRES_NEW

在这里插入图片描述

我们为 User1Service 和 User2Service 相应方法加上Propagation.REQUIRES_NEW属性。
在这里插入图片描述
在这里插入图片描述

3.1.场景1——外围方法没有开启事务

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

3.2. 场景2——外围方法开启事务

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

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

3.x. 对比以上这3种 REQUIRED、REQUIRES_NEW、NESTED
4.1. REQUIRED、NESTED
  • 1.都会受外围回滚影响:他俩修饰的内部方法 都属于外围方法事务,外围方法抛出异常,这两种方法的事务都会回滚
  • 2.可不可以被catch:
    • REQUIRED是加入外围方法的事务,内外一体,一旦内部方法的事务抛出异常,无论会不会被内部方法自己catch,外围方法的事务一样会回滚
    • NESTED修饰的是外围方法的嵌套子事务,有单独的保存点,所以他抛出异常被catch掉不会影响外围方法的事务。
4.2. Nested与Requires_News
  • 1.都可以被catch,那会不会被外围方法影响?:他俩 都可以做到内部方法事务回滚不影响外围方法的事务。
    • 但是因为nested是嵌套子事务,所以外围方法回滚,他作为外围事务的子事务也会被回滚。
    • Requires_New是通过开启新事务实现的,内外事务是两个事务,外围回滚不影响内部事务
4.3.Nested与Requires_News、REQUIRED

REQUIRED,无论内部事务catch与否,内外一定会互相影响
Nested: 可以通过catch做到 内可以不影响外,但是外一定会影响内
Requires_News:内可以通过catch不影响外外一定影响不了内

4.PROPAGATION_MANDATORY
  • 1.如果已经存在1个事务,支持当前事务;
  • 2.如果没有1个活动事务,则抛出异常
代码分析:
  • 1.单独调用方法methodB时,因为当前没有一个活动的事务,则会抛出异常;
  • 2.当调用方法methodA时,methodB则加入到methodA的事务中,事务的执行。
@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {
 methodB();
// do something
}
 
 事务属性为MANDATORY
@Transactional(propagation = Propagation.MANDATORY)
public void methodB() {
     do something();
}
5.PROPAGATION_SUPPORTS
  • 1.如果存在一个事务,支持当前事务;
  • 2.如果没有事务,则非事务的执行。
代码分析
  • 1.单独的调用methodB时,它会非事务的执行;
  • 2.调用methodA时,methodB则加入methodA的事务中,事务地执行;
@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {
 methodB();
// do something
}
 
 事务属性为SUPPORTS
@Transactional(propagation = Propagation.SUPPORTS)
public void methodB() {
     do something();
}
6.PROPAGATION_NOT_SUPPORTED
  • 1.他总是非事务的执行,并挂起任何存在的事务;
    他也需要使用JtaTransactionManager作为事务管理器。
代码分析:
  • 1.单独调用methodB时,无事务的执行;
  • 2.调用methodA时,执行到methodB时会挂起事务A,以非事务的方式执行methodB;
    在这里插入图片描述
7.PROPAGATION_NEVER

总是非事务的执行,如果存在1个活动事务,则会抛出异常

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值