Spring——IOC、AOP、事务
作者:互联网
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类似的逆向操作。
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属性。
2.1 场景一
此场景外围方法没有开启事务。
2.2.场景二——外围方法开启事务。
3.Propagation.REQUIRES_NEW
我们为 User1Service 和 User2Service 相应方法加上Propagation.REQUIRES_NEW属性。
3.1.场景1——外围方法没有开启事务
3.2. 场景2——外围方法开启事务
4. 对比以上这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
REQUIRED,无论内部事务catch与否,内外一定会互相影响
Nested: 可以通过catch做到 内可以不影响外,但是外一定会影响内
Requires_News:内可以通过catch不影响外,外一定影响不了内
标签:容器,事务,Spring,Bean,外围,AOP,方法,IOC 来源: https://blog.csdn.net/m0_38057941/article/details/115976121