SpringBean的生命周期
spirng根据类实例化对象后,对加了@Autowired、@Resource注解的属性进行赋值(属性填充)、进行对象初始化(@PostConstruct注解)、判断是否需要AOP(配置控制)需要的话AOP生成代理对象、代理对象注册成bean
spring 单例bean,bean按照type和name获取,spring有类似于map的结构存储bean,key为bean的name,value为bean,spring中该类似于map的容器叫单例缓存池。
获取流程 byType ——>根据Type从Spring容器里找到多个Bean———>查看bean是否(@autoWireCandidate = false过滤掉)————>是不是符合Qualifier(@Qualifier(”name”))分组——->取@Primary标注了的bean——->取优先级最高的Bean————>根据属性名字选出一个
@Autowire spring提供
bytype 再byName
@Resource java提供
byName找不到再 byType
Spring事务
开启事务相关注解:
@Configuration
@EnableTransactionManagement
@Transaction
Spring事务传播机制
spring事务传播的含义
简单的理解就是多个事务方法相互调用时,事务如何在这些方法间传播。默认是REQUIRED。
7种事务传播类型
按对当前事务的支持情况7种传播类型可分为三组
支持当前事务类型:
1 REQUIRED (必须有)
如果当前存在事务,则加⼊该事务;如果当前没有事务,则创建⼀个新的事务。
2 SUPPORTS (可有可无)
如果当前存在事务,则加⼊该事 务;如果当前没有事务,则以⾮事务的⽅式继续运⾏。
3 MANDATORY (强制)
如果当前存在事务,则加⼊该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)
不支持当前事务
4 REQUIRES_NEW
创建⼀个新的事务,如果当前存在事务,则把当前事务挂起。
5 NOT_SUPPORTED
以⾮事务⽅式运⾏,如果 当前存在事务,则把当前事务挂起。
6 NEVER
以⾮事务⽅式运⾏,如果当前存在事务,则抛出异常。
其他
7 NESTED
如果当前存在事务,则创建⼀个事务 作为当前事务的嵌套事务来运⾏;如果当前没有事务,则该取值等价于 REQUIRED。即新创建事务。
事务传播机制demo示例
REQUIRED
1 | (propagation = Propagation.REQUIRED) |
由于testMain方法存在事务且调用testB方法,testB方法的事务会加入testMain的事务之中。testB抛出运行异常所以testMain方法和testB方法都会回滚。
1 | public void testMain(){ |
由于testMain没有事务所以testB会新创建一个事务,testB方法发生回滚。
SUPPORTS
1 | public void testMain(){ |
由于testMain方法没有事务,testB将以非事务运行,B(b1)将执行,B(b2)不执行。
MANDATORY
1 | public void testMain(){ |
testB方法将直接抛出异常,B(b1)方法不执行。
REQUIRES_NEW
1 | (propagation = Propagation.REQUIRED) |
testMain方法发生回滚,testB方法成功执行。
NOT_SUPPORTED
1 | (propagation = Propagation.REQUIRED) |
testB方法中没有事务,B(b1)方法成功执行。testMain方法回滚,A(a1)不执行。
NEVER
1 | (propagation = Propagation.REQUIRED) |
由于testMain方法存在事务,testB方法将抛出异常,testMain方法发生回滚所有方法都不执行。
NESTED
如果当前存在事务,则在嵌套事务(创建子事务)内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
- 和REQUIRES_NEW的区别
REQUIRES_NEW是新建一个事务并且新开启的这个事务与原有事务无关,而NESTED则是当前存在事务时(我们把当前事务称之为父事务)会开启一个嵌套事务(称之为一个子事务)。
在NESTED情况下父事务回滚时,子事务也会回滚,而在REQUIRES_NEW情况下,原有事务回滚,不会影响新开启的事务。
- 和REQUIRED的区别
REQUIRED情况下,调用方存在事务时,则被调用方和调用方使用同一事务,那么被调用方出现异常时,由于共用一个事务,所以无论调用方是否catch其异常,事务都会回滚
而在NESTED情况下,被调用方发生异常时,调用方可以catch其异常,这样只有子事务回滚,父事务不受影响
1 | (propagation = Propagation.REQUIRED) |
testMain方法和testB方法都不会执行,父事务回滚子事务也会发生回滚。
1 | (propagation = Propagation.REQUIRED) |
testMain方法捕获了testB方法的异常,所以只有子事务发生回滚。
注意:虽然是2个事务,但由于方法a()抛出异常,test()方法内调用,相当于test方法内抛出了异常,所以事务回滚2个事务的方法都不执行。
该情况a()方法将执行,test()方法将回滚。
待续….
...
...
This is copyright.