RabbitMQ相關問題
Spring框架相關問題
- 一、Spring容器中的Bean是線程安全的嗎?
- 二、如何保證Spring容器中的Bean是線程安全的呢?
- 三、什么情況下會觸發Spring事務回滾?
- 四、如果事務方法拋出IOException,是否會觸發Spring事務回滾?
- 五、什么情況下Spring事務會失效呢?
- 六、對Spring框架Bean的生命周期有了解過嗎?
一、Spring容器中的Bean是線程安全的嗎?
答案:不是線程安全的;
- Spring容器中的
Bean
默認是singleton
單例的,所有線程都共享一個單例Bean,因此是存在資源競爭的; - 但在實際開發中,單例 Bean 一般都以無狀態的方式來使用,即線程之間的操作不會對 Bean 的成員執行除查詢以外的操作,所以這個單例 Bean 又可以說是線程安全的。比如:Controller、Service、Dao等這些Bean大多數是無狀態的,我們不會對這些Bean中的屬性
進行修改操作,只需要關注方法本身即可;
二、如何保證Spring容器中的Bean是線程安全的呢?
1、把默認的 singleton
單例的 Bean 的改為 prototype
多例的Bean; 添加注解:@Scope("prototype")
2、在 Bean 對象中避免定義可變的成員變量;
3、如果 Bean 對象中需要定義可變成員變量,將可變成員變量保存在 ThreadLocal
中;
private ThreadLocal<Integer> numberThreadLocal = ThreadLocal.withInitial(() -> {return 0;
});
三、什么情況下會觸發Spring事務回滾?
當執行發生異常的時候,觸發Spring事務回滾。
@Transactional(rollbackFor = Exception.class)
四、如果事務方法拋出IOException,是否會觸發Spring事務回滾?
如果采用Spring默認的事務回滾規則,它默認是發生RuntimeException
異常時觸發事務回滾,而現在是發拋出IOException
異常,那不會觸發Spring事務回滾;
如果想觸發IOException
異常事務回滾,需要指定回滾的規則;
@Transactional(rollbackFor = IOException.class)
五、什么情況下Spring事務會失效呢?
- 考察對Spring的事務管理理解是否深刻;
- 先舉幾個示例,進行分析,然后再總結答案;
1、同一個Service中,方法A 標注事務注解,則方法B 沒有標注事務注解;
2、同一個Service中,沒有標注事務注解的B方法調用標注了事務注解的A方法;事務失效
3、不同的Service中,沒有標注事務注解的B方法調用標注了事務注解的A方法;事務不失效
4、標注了事務注解的public方法、protected方法、默認無修飾方法、private方法,final方法,static方法;只有Public方法事務生效;
5、多線程中的事務;事務失效
事務失效情況:
1、異常類型錯誤;IOException類型
2、方法或類上沒有標注@Transactional注解;
3、同一類中,方法內部自調用;
4、事務方法不是public的;
5、多線程調用;
6、異常被try … catch
7、手動拋了別的異常 IOException
8、事務方法所在的Bean未被 Spring 容器管理
9、方法的事務傳播類型不支持事務
10、表的數據庫引擎不支持事務,比如MyISAM存儲引擎不支持事務;
六、對Spring框架Bean的生命周期有了解過嗎?
1、解析 xml 配置或者注解的類,得到 BeanDefinition
;
2、通過 BeanDefinition
反射創建 Bean
對象(實例化 Bean 對象)。
3、對 Bean
對象進行屬性填充
4、回調實現 Aware 接口的方法,比如 BeanNameAware
5、調用BeanPostProcessor
的初始化前方法;
6、調用init
初始化方法(如果有的話);
7、調用BeanPostProcessor
的初始化后方法,此處會進行 AOP;
8、將創建好的 Bean 對象放入一個 Map 中;
9、業務中使用 Bean 對象就從 Map 中獲取;
10、Spring 容器關閉時調用 DisposableBean
的 destory
方法銷毀 Bean 對象;