一、概述
1.什么是Spring
Spring诞生的目的是致力于全面的简化JAVA的企业级应用开发。 // 也可以理解为是一个管理型的框架
使用Spring框架开发, 对于项目的代码入侵性小。
Spring框架内部使用了众多的设计模式 : 工厂模式、 单例模式、原型模式、代理模式、策略模式 等等
二、Spring事务
1、事务控制
1.1事务:事务是用户操作数据库的基本单元。组成事务的一组sql要么一起成功,要么一起失败。
2.JDBC中如何手动控制事务:
2.1 设置手动控制事务: conn.setAutoCommit(false);
2.2 手动提交: conn.commit();
2.3 手动回滚: conn.rollback();
3.Spring中提供的管理事务的对象:
-DataSourceTransactionManager // 负责事务的管理,依赖于数据源(dataSource)
4.Spring管理事务的思想:
4.1 Spring中的事务管理是基于AOP思想展开的。
4.2 Spring中管理事务的方式,我们也称为声明式事务管理。
5. Spring事务管理的开发流程
5.1 创建原始类 – 创建service对象
5.2 编写额外功能 – 事务控制相关配置
6.事务属性
6.1 传播性
- PROPAGATION_REQUIRED : 会主动开启新的事务。 // 适用于 增 删 改
支持事务,事务是必须的, 如果外层有事务,会主动加入外层的事务。 外层没有事务, 会自己创建一个新的事务。 - PROPAGATION_SUPPORTS : 不会主动开启新的事务。 // 适用于 查询
支持事务, 如果外层有事务,会加入外层的事务。 外层没有事务,不创建事务。 - PROPAFATION_REQUIRES_NEW : 创建一个新的事务。
外层有事务, 先挂起,创建一个自己的新的事务。 - PROPAGATION_MANDATORY :
外层有事务,加入外层事务。 外层没有事务,则抛异常。 - PROPAGATION_NEVER : 不支持事务 。
外层有事务,抛异常。 - PROPAGATION_NOT_SUPPORTED : 以非事务的方式运行。
外层有没有事务, 我都正常以没有事务的方式运行。
6.2 隔离性
-
事务的隔离性是指,在并发的场景下, 事务之间的相互影响程度。
1)脏读
一个事务读取到了另一个事务,没有提交的数据。2)修改丢失(Lost of modify):是指一个事务读取一个数据时,另外一个数据也访问了该数据,那么在第一个事务修改了这个数据之后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,这种情况就被称为修改丢失。例如:事务1读取表中数据A=20,事务2也读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果都是19,但是事务1的修改记录丢失了。
3)不可重复读
指在一个事务内多次读取同一数据,在这个事务还没结束时,另外一个事务也访问了这个数据并对这个数据进行了修改,那么就可能造成第一个事务两次读取的数据不一致,这种情况就被称为不可重复读。4)幻影读
幻读与不可重复读类似,幻读是指一个事务读取了几行数据,这个事务还没结束,接着另外一个事务插入了一些数据,在随后的查询中,第一个事务读取到的数据就会比原本读取到的多,就好像发生了幻觉一样,所以称为幻读。 -
事务的隔离级别:
1)读未提交 - read uncommitted : 一个事务可以读取到另一个事务未提交的数据。
会导致: 脏读 不可重复读 幻影读
安全性: 极差 效率: 很高
2)读提交 - read committed : 一个事务只能读取到另一个事务提交后的数据。
避免了:脏读 会导致: 不可重复读 幻影读
安全性:稍差 效率: 一般
3)可重复读 - repeatable read :
这是mysql的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。
避免了: 脏读 不可重复读 会导致: 幻影读
安全性: 高 效率: 差
4)序列化读 :
这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争,因此使用该隔离级别会造成数据库性能的显著下降。
避免了: 脏读 不可重复读 幻影读
安全性: 极好 效率: 极差
注意: oracle默认的隔离级别读提交 。 目前开发采用默认的就可以。
6.3 回滚性
Spring默认回滚策略:
- 当抛出运行时异常,事务自动做回滚处理。
- 当抛出非运行时异常, 事务自动提交。
- 自定义回滚策略: 是指当程序抛出指定异常类型时, 是否做回滚处理。
6.4 超时性
超时性,是指一个事务从开始执行,到事务结束的最大允许时间。
6.5 只读性
事务的只读性,是指一个事务只允许进行查询的操作。不能进行增 删 改。
三、 Spring FactoryBean和BeanFactory 区别
1.BeanFactory是个bean 工厂,是一个工厂类(接口), 它负责生产和管理bean的一个工厂,是ioc 容器最底层的接口,是个ioc容器,是spring用来管理和装配普通bean的ioc容器(这些bean成为普通bean)。
2.FactoryBean是个bean,在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式,是一个可以生产对象和装饰对象的工厂bean,由spring管理后,生产的对象是由getObject()方法决定的。
四、BeanFactoryPostProcessor和BeanPostProcessor区别
1.BeanFactoryPostProcessor是用来处理修改bean定义信息的后置处理器,这个时候bean还没有初始化,只是定好了BeanDefinition,在BeanFactoryPostProcessor接口的postProcessBeanFactory方法中,我们可以修改bean的定义信息,例如修改属性的值,修改bean的scope为单例或者多例。
@FunctionalInterface
public interface BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for overriding or adding
* properties even to eager-initializing beans.
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
//这个是所有的bean的定义信息定义好之后,初始化前的最后一次提供修改的操作,这里一般都是用来修改bean的定义信息或者修改bean的属性用的,这个接口没有提供默认的实现方法,它是一个void方法
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
2.BeanPostProcessor则是bean初始化前后对bean的一些操作,意思就是说bean在调用构造之后,初始化方法前后进行一些操作。
进入实现BeanPostProcessor类的方法里面的bean都是已经实例化好的,可以直接用来使用,也就是参数里面的bean可以直接转成我们需要的对象,然后进行属性操作,例如你可以在这里对bean进行设置值,一般来说我们都是在用自定义注解的时候会判断这些bean的字段是否包含我们的自定义注解,当然了还有其他的一些用途,看自己怎么使用了。这里需要主要的一点是在高版本的BeanPostProcessor这个接口,都使用了default实现了默认写法
public interface BeanPostProcessor {
//初始化调用方法之前调用(一般我们说来就是initMethod方法或者@PostConstruct注解方法,当然还有其他的方式实现初始化方法),是在构造方法之后执行的
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
//初始化方法之后进行调用
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}