Spring框架一
Spring框架一
一、Spring Bean的作用域
一、名词解释
1、在Spring中,可以在
元素的scope属性里设置bean的作用域,以决定这个bean是单实例的还是多实例的。
2、默认情况下,Spring只为每个在1OC容器里声明的bean创建唯一一个实例,整个1OC容器范围内都能共享该实例:所有后续的 getBean()调用和 bean引用都将返回这个唯一的bean实例。该作用域被称为singleton,它是所有bean的默认作用域。
| 类别 | 说明 |
|---|---|
| singleton | 在SpringlOC容器中仅存在一个Bean实例,Bean以单实例的方式存在prototype 每次调用getBean)时都会返回一个新的实例 |
| prototype | 每次调佣getBean()时都会返回一个新的实例 |
| request | 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext 环境 |
| session | 用一个HTTP Session共享一个Bean,不同的HTTP Session使用不同的Bean,该作用域仅适用于WebApplicationContext 环境 |
当Bean的作用域为单例时,Spring会在IOC容器对象创建时就创建Bean的对象实例。
二、代码示例
代码示例:
public class SprBean {
private int id;
private int age;
private String sex;
public SprBean() {
System.out.println("SprBean无参对象被创建了");
}
public SprBean(int id, int age, String sex) {
this.id = id;
this.age = age;
this.sex = sex;
System.out.println("SprBean有参对象被创建了");
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
测试类
import com.demo.SprBean;
import org.junit.Test;
public class SprBeanTest {
//创建IOC容器对象
AppliactionContext ioc = new ClassPathXmlAppliactionContext("beans.xml");
@Test
public void test(){
SprBean bs1 = (SprBean) ioc.getBean("sBean");
SprBean bs2 = (SprBean) ioc.getBean("sBean");
System.out.println(bs1 == bs2);
}
}
文本类:beans.xml
<bean id="sBean" class="com.demo.SprBean" scope="singLeton">
<propert name="id" value="2"></propert>
<propert name="age" value="16"></propert>
<propert name="sex" value="男"></propert>
</bean>
运行结果:
bean作用域为:singLeton
"C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\JAVA\idea\IntelliJ IDEA com.demo.Step1
SprBean无参对象被创建了
true
Process finished with exit code 0
bean作用域为:prototype
"C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:E:\JAVA\idea\IntelliJ IDEA com.demo.Step1
SprBean无参对象被创建了
SprBean无参对象被创建了
false
Process finished with exit code 0
二、Spring支持的数据库事务
事务是用户定义的数据库序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位
一、事务传播行为
一个方法运行在了一个开启事务的方法中时,当前方法是使用原来的事务还是开启一个新的事务!
spring定义了7种事务传播行为:
| 传播属性 | 描述 |
|---|---|
| REQUIRED | 如果有事务在运行,当前的方法就在这个事务内运行,否则,就启动一个新的事务,并在自己的事务内运行 |
| REQUIRES_NEW | 当前的方法必须启动新事务,并在它自己的事务内运行.如果有事务正在运行,应该将它挂起 |
| SUPPORTS | 如果有事务在运行,当前的方法就在这个事务内运行.否则它可以不运行在事务中. |
| NOT_SUPPORTE | 当前的方法不应该运行在事务中,如果有运行的事务,将它挂起 |
| MANEATORY | 当前的方法必须运行在事务内部,如果没有正在运行的事务,就抛出异常 |
| NEVED | 当前的方法不应该运行在事务中,如果有运行的事务,就抛出异常 |
| NESTED | 如果有事务在运行,当前的方法就应该在这个事务的嵌套事务内运行.否则,就启动一个新的事务,并在它自己的事务内运行 |
事务传播属性可以在@Transactional注解的propagation属性中定义。
二、事务的特性
事务具有4个特性:
原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持续性(Durability)。这4个特性简称为ACID特性
- 原子性:事务是一个原子性质的操作单元,事务里面的对数据库的操作要么都执行,要么都不执行。
- 一致性:在事务开始之前和完成之后,数据都必须保持一致状态,必须保证数据库的完整性。也就是说,数据必须符合数据库的规则。
- 隔离性:一个事务的执行不能被其他事务干扰。即一个事务的内部操作及使用的数据对其他并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
- 持久性:持久性也成为永久性,指一个事务一旦提交,它对数据库中数据的改变就应该是永久的。
三、事务隔离
一、事务并发问题
- 脏读:事务A读到了事务B更新但未提交的数据;
- 幻读:在两个事务对数据表同时修改时,事务A修改之后读取到事务B修改过的数据。
- 不可重复读:事务A对数据表第一次读取到数据后,事务B对该表数据进行修改,导致事务A再次读取数据时与第一次的数据不一致。
二、隔离级别
-
读未提交(Read Uncommitted):在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)
-
读已提交(Read Committed):这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别也支持所谓的不可重复读(NonrepeatableRead),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果
-
可重复读(Repeatable Read):这是MySQL的默认事务隔离级别,同一事务的多个实例在并发读取数据时,会看到同样的数据。不过理论上,这会导致另一个棘手的问题:幻读(Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。
-
可串行化(Serializable):这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争
三、隔离影响
四种隔离级别越往后越影响性能,如何选取根据业务需求而定。以下是四种隔离级别中对脏读、不可重复读、幻读的影响情况:
| 脏读 | 幻读 | 不可重复读 | |
|---|---|---|---|
| 读未提交 | √ | √ | √ |
| 读已提交 | × | √ | √ |
| 可重复读 | × | × | √ |
| 串行化 | × | × | × |

浙公网安备 33010602011771号