Spring Bean的Scope作用域詳解
Spring Bean的Scope作用域
Spring框架中的Bean Scope(作用域)用于控制Bean的生命周期和可見性。
Spring提供了多種作用域,每種作用域決定了Bean在應(yīng)用中的創(chuàng)建和管理方式。
以下是Spring中最常用的作用域及其特點(diǎn):
Scope作用域類型
1. Singleton(單例)
- 默認(rèn)作用域: 如果沒有顯式指定作用域,默認(rèn)就是Singleton。
- 生命周期: 在整個(gè)應(yīng)用中,只有一個(gè)實(shí)例。這個(gè)實(shí)例在Spring容器啟動(dòng)時(shí)創(chuàng)建,并且在整個(gè)應(yīng)用運(yùn)行期間一直存在。
- 適用場景: 適用于無狀態(tài)的Bean,如服務(wù)層和DAO層的Bean。
@Component @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) public class MySingletonComponent { // ... }
2. Prototype(原型)
- 生命周期: 每次請(qǐng)求都會(huì)創(chuàng)建一個(gè)新的實(shí)例。Spring容器在創(chuàng)建原型Bean后,就不再管理其生命周期。
- 適用場景: 適用于有狀態(tài)的Bean,如需要每個(gè)請(qǐng)求都獨(dú)立處理的Bean。
@Component @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class MyPrototypeComponent { // ... }
在Spring框架中,使用@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
修飾的@Component
表示該組件是一個(gè)原型(Prototype)作用域的bean。
這意味著每次通過Spring容器請(qǐng)求這個(gè)bean時(shí),都會(huì)創(chuàng)建一個(gè)新的實(shí)例。
與單例(Singleton)作用域的bean不同,原型作用域的bean不會(huì)被緩存,每次請(qǐng)求都會(huì)返回一個(gè)新的實(shí)例。
生命周期
每次請(qǐng)求都創(chuàng)建新實(shí)例:
- 每次調(diào)用
context.getBean(MyPrototypeComponent.class)
時(shí),都會(huì)創(chuàng)建一個(gè)新的MyPrototypeComponent
實(shí)例。 - 這意味著每個(gè)請(qǐng)求之間是隔離的,每個(gè)實(shí)例都有獨(dú)立的狀態(tài)。
生命周期管理:
- 原型作用域的bean的生命周期由創(chuàng)建它的客戶端代碼負(fù)責(zé)管理。Spring容器只負(fù)責(zé)初始化和裝配bean,一旦bean被創(chuàng)建并返回給客戶端代碼,容器就不再管理其生命周期。
- 容器不會(huì)調(diào)用銷毀方法(如
@PreDestroy
注解的方法)來清理資源,因?yàn)槿萜鞑恢篮螘r(shí)應(yīng)該銷毀這些bean,這也反向說明了原型Bean被Spring創(chuàng)建后就不在管理其生命周期了。
在Spring框架中,當(dāng)一個(gè)Bean的作用域被設(shè)置為SCOPE_PROTOTYPE
時(shí),這個(gè)Bean在容器啟動(dòng)時(shí)不會(huì)被自動(dòng)實(shí)例化。相反,每次通過Spring容器請(qǐng)求這個(gè)Bean時(shí),才會(huì)創(chuàng)建一個(gè)新的實(shí)例。
關(guān)鍵總結(jié)
Singleton作用域:
- 默認(rèn)作用域。
- 在容器啟動(dòng)時(shí)被實(shí)例化一次。
- 整個(gè)應(yīng)用生命周期內(nèi)只存在一個(gè)實(shí)例。
Prototype作用域:
- 每次請(qǐng)求時(shí)都會(huì)創(chuàng)建一個(gè)新的實(shí)例(也是每次請(qǐng)時(shí)才會(huì)創(chuàng)建,一個(gè)被定義為該作用域的類如果沒有在任何地方使用它,那么你可以認(rèn)為它和一個(gè)普通的Java類沒有區(qū)別)。
- 請(qǐng)求的方式包括注入該Bean到其他Bean里,每注入一個(gè)地方都是一個(gè)獨(dú)立的Bean?;蛘呤褂?
context.getBean
方式獲取Bean的時(shí)候。 - 容器啟動(dòng)時(shí)不會(huì)自動(dòng)實(shí)例化。
- 容器在創(chuàng)建Bean后不再管理其生命周期。
- 特別適合那種需要注入Spring中其他類的Java類,但是這個(gè)類又是在某些場景需要的時(shí)候才需要實(shí)例化的場景,例如實(shí)現(xiàn) Runnable 接口的線程任務(wù)類。
示例:
@Data @Accessors(chain = true) @Component @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class Task implements Runnable { private TaskInfo taskInfo; // 注入對(duì)象 @Autowired private TaskService taskService; @Override public void run() { taskService.process(taskInfo); } }
// 調(diào)用示例代碼 ApplicationContext context = xxx; ExecutorService executor = xxx; TaskInfo taskInfo = xxx; // 這里每次getBean獲取的Task對(duì)象都是一個(gè)新的實(shí)例 Task task = context.getBean(Task.class).setTaskInfo(taskInfo); executor.execute(task);
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
一文詳解如何在控制臺(tái)顯示MyBatis的SQL語句
這篇文章主要為大家介紹了如何在控制臺(tái)顯示MyBatis的SQL語句實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06解析Java?中for循環(huán)和foreach循環(huán)哪個(gè)更快
這篇文章主要介紹了Java中for循環(huán)和foreach循環(huán)哪個(gè)更快示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09詳解關(guān)于IntelliJ IDEA中Schedule for Addition 的問題
本篇文章主要介紹了詳解關(guān)于 IntelliJ IDEA 中 Schedule for Addition 的問題,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12這么設(shè)置IDEA中的Maven,再也不用擔(dān)心依賴下載失敗了
今天給大家?guī)硪粋€(gè)IDEA中Maven設(shè)置的小技巧.這個(gè)技巧可以說非常有用,學(xué)會(huì)設(shè)置之后,再也不用擔(dān)心maven依賴下載變慢的問題,需要的朋友可以參考下2021-05-05mybatis resultType自帶數(shù)據(jù)類型別名解讀
MyBatis為了簡化開發(fā),通過org.apache.ibatis.type.TypeAliasRegistry為常見類定義了別名,這些別名包括基本數(shù)據(jù)類型及其數(shù)組、集合類型等,如string對(duì)應(yīng)java.lang.String,int對(duì)應(yīng)java.lang.Integer等,此外,還有特殊前綴的別名如_int對(duì)應(yīng)int類型2024-10-10Java中JSON字符串進(jìn)行各種轉(zhuǎn)換的方法小結(jié)
Gson和Hutool的JSONUtil都是常用的用于處理JSON數(shù)據(jù)的工具庫,它們提供了簡單易用的API來進(jìn)行JSON字符串的解析、轉(zhuǎn)換和操作,下面就跟隨小編一起學(xué)習(xí)一下如果使用他們實(shí)現(xiàn)JSON字符串的各種轉(zhuǎn)換吧2024-01-01MyBatis學(xué)習(xí)教程之開發(fā)Dao的方法教程
這篇文章主要給大家介紹了關(guān)于MyBatis開發(fā)Dao的相關(guān)資料,使用Mybatis開發(fā)Dao,通常有兩個(gè)方法,即原始Dao開發(fā)方法和Mapper接口開發(fā)方法。文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面來一起看看吧。2017-07-07