Java多例Bean的應(yīng)用場(chǎng)景-easyExcel導(dǎo)入
1. bean注入方式(IOC)
2. 有狀態(tài)會(huì)話bean和無狀態(tài)會(huì)話bean
有狀態(tài)會(huì)話bean
:每個(gè)用戶有自己特有的一個(gè)實(shí)例,在用戶的生存期內(nèi),bean保持了用戶的信息,即“有狀態(tài)”;一旦用戶滅亡(調(diào)用結(jié)束或?qū)嵗Y(jié)束),bean的生命期也告結(jié)束。即每個(gè)用戶最初都會(huì)得到一個(gè)初始的bean。
無狀態(tài)會(huì)話bean
:bean一旦實(shí)例化就被加進(jìn)會(huì)話池中,各個(gè)用戶都可以共用。即使用戶已經(jīng)消亡,bean 的生命期也不一定結(jié)束,它可能依然存在于會(huì)話池中,供其他用戶調(diào)用。由于沒有特定的用戶,那么也就不能保持某一用戶的狀態(tài),所以叫無狀態(tài)bean。但無狀態(tài)會(huì)話bean 并非沒有狀態(tài),如果它有自己的屬性(變量),那么這些變量就會(huì)受到所有調(diào)用它的用戶的影響,這是在實(shí)際應(yīng)用中必須注意的。
面試題:?jiǎn)卫?Bean 存在線程安全問題嗎?
答:在 Bean 中盡量避免定義可變的成員變量。推薦的做法時(shí)在類中定義一個(gè) ThreadLocal 成員變量,將需要的可變成員變量保存在 ThreadLocal 中。
不過,大部分 Bean 實(shí)際都是無狀態(tài)(沒有實(shí)例變量)的(比如 Dao、Service),這種情況下, Bean 是線程安全的。
3. 單例模式和多例模式
@Scope注解主要作用是調(diào)節(jié)Ioc容器中的作用域,在Spring IoC容器中主要有以下幾種作用域:
基本作用域:singleton(單例)、prototype(多例);
Web 作用域(reqeust、session、globalsession);
自定義作用域。
目前有90%以上的業(yè)務(wù)系統(tǒng)都使用singleton單實(shí)例,因此spring也默認(rèn)的類型也是singleton,singleton保證了全局是一個(gè)實(shí)例,對(duì)性能有所提高,但是如果實(shí)例中有非靜態(tài)變量時(shí),可能會(huì)導(dǎo)致線程安全、共享資源的競(jìng)爭(zhēng)等問題。
當(dāng)設(shè)置為prototype(多實(shí)例)時(shí):每次連接請(qǐng)求,都會(huì)重新生成一個(gè)新的bean實(shí)例,這也會(huì)導(dǎo)致一個(gè)問題,當(dāng)請(qǐng)求數(shù)越多,性能會(huì)降低,因?yàn)轭l繁創(chuàng)建的新的實(shí)例,會(huì)導(dǎo)致GC頻繁,GC回收時(shí)長(zhǎng)增加。要根據(jù)實(shí)際情況選擇哪一種方式。
4. 深挖多例模式應(yīng)用場(chǎng)景?
在Spring中,prototype原型模式(多例模式)使用的場(chǎng)景不多,只有當(dāng)你的bean的屬性中會(huì)有數(shù)據(jù)存在的時(shí)候,才需要使用原型模式,否則數(shù)據(jù)就串了。我自己使用過的一個(gè)場(chǎng)景是用EasyExcel實(shí)現(xiàn)導(dǎo)入功能的時(shí)候會(huì)使用到。
在使用EasyExcel讀取表格文件時(shí),官方文檔推薦的是自己進(jìn)行new一個(gè)Listener對(duì)象,但是想在這個(gè)對(duì)象中使用其他service對(duì)象的話,就不能使用@Autowired了,因?yàn)檫@個(gè)Listener對(duì)象并不受容器管理。其中Listener對(duì)象中用到的其他service或者DAO類通過構(gòu)造方法初始化進(jìn)去,如果直接用@Autowired注入會(huì)報(bào)空指針錯(cuò)誤,項(xiàng)目中代碼如下:
Controller代碼:
Listener代碼:
我們可以考慮將這個(gè)Listener對(duì)象變成多例模式,加上@Component和@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)兩個(gè)注解:
然后在Controller里面通過Spring容器獲取這個(gè)對(duì)象(注意:一定要通過容器手動(dòng)獲取,prototype原型模式的bean如果還通過@Autowired的形式注入的話,這個(gè)對(duì)象還是同一個(gè),因?yàn)锧Autowired只會(huì)注入一次)
調(diào)用方通過Spring注入的方式自動(dòng)注入EmployeeHouseImportListener,而非new的方式,這樣獲取到的EmployeeHouseImportListener是被Spring容器管理的,進(jìn)而可以在EmployeeHouseImportListener中通過@Autowired的方式成功獲取到同樣被Spring容器管理的UserService,因?yàn)閁serService 的實(shí)現(xiàn)類中有"@Service"注解標(biāo)記。
//調(diào)用方 EmployeeHouseImportListener importListener = SpringUtils.getBean("employeeHouseImportListener");
到此這篇關(guān)于Java多例Bean的應(yīng)用場(chǎng)景-easyExcel導(dǎo)入的文章就介紹到這了,更多相關(guān)Java Bean應(yīng)用場(chǎng)景內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java編程文件遍歷之指定遍歷的層數(shù)詳細(xì)代碼
這篇文章主要介紹了Java編程文件遍歷之指定遍歷的層數(shù)詳細(xì)代碼,具有一定借鑒價(jià)值,需要的朋友可以參考下。2017-12-12JAVA利用接口實(shí)現(xiàn)多繼承問題的代碼實(shí)操演示
Java語言并不支持多繼承,這是由于多繼承會(huì)帶來許多復(fù)雜的問題,例如"菱形問題"等,下面這篇文章主要給大家介紹了關(guān)于JAVA利用接口實(shí)現(xiàn)多繼承問題的相關(guān)資料,需要的朋友可以參考下2024-03-03JAVA LinkedList和ArrayList的使用及性能分析
JAVA LinkedList和ArrayList的使用及性能分析,這篇文章也是以JAVA List的總結(jié)。2013-11-11詳解java實(shí)現(xiàn)簡(jiǎn)單掃碼登錄功能(模仿微信網(wǎng)頁版掃碼)
這篇文章主要介紹了java實(shí)現(xiàn)簡(jiǎn)單掃碼登錄功能(模仿微信網(wǎng)頁版掃碼),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05java 查詢oracle數(shù)據(jù)庫所有表DatabaseMetaData的用法(詳解)
下面小編就為大家?guī)硪黄猨ava 查詢oracle數(shù)據(jù)庫所有表DatabaseMetaData的用法(詳解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-11-11springboot反爬蟲組件kk-anti-reptile的使用方法
這篇文章主要介紹了springboot反爬蟲組件kk-anti-reptile的使用方法,幫助大家更好的利用spring boot反爬蟲,保護(hù)網(wǎng)站安全,感興趣的朋友可以了解下2021-01-01Java 基于UDP協(xié)議實(shí)現(xiàn)消息發(fā)送
這篇文章主要介紹了Java 基于UDP協(xié)議實(shí)現(xiàn)消息發(fā)送,幫助大家更好的理解和學(xué)習(xí)Java網(wǎng)絡(luò)編程,感興趣的朋友可以了解下2020-11-11JavaFX實(shí)現(xiàn)UI美觀效果代碼實(shí)例
這篇文章主要介紹了JavaFX實(shí)現(xiàn)UI美觀效果代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07