詳解Spring中Bean的作用域與生命周期

      網(wǎng)友投稿 774 2025-03-31

      目錄


      一、Bean的作用域

      1、單實(shí)例Bean聲明

      2、多實(shí)例Bean聲明

      二、Bean的生命周期

      1、bean的初始和銷毀

      2、bean的后置處理器

      Hello,你好呀,我是灰小猿!一個(gè)超會寫bug的程序猿!

      在利用spring進(jìn)行IOC配置時(shí),關(guān)于bean的配置和使用一直都是比較重要的一部分,同時(shí)如何合理的使用和創(chuàng)建bean對象,也是小伙伴們在學(xué)習(xí)和使用spring時(shí)需要注意的部分,所以這一篇文章我就來和大家講一下有關(guān)Spring中bean的作用域和其生命周期。

      一、Bean的作用域

      首先我們來講一下有關(guān)于bean的作用域,

      一般情況下,我們書寫在IOC容器中的配置信息,會在我們的IOC容器運(yùn)行時(shí)被創(chuàng)建,這就導(dǎo)致我們通過IOC容器獲取到bean對象的時(shí)候,往往都是獲取到了單實(shí)例的Bean對象,

      這樣就意味著無論我們使用多少個(gè)getBean()方法,獲取到的同一個(gè)JavaBean都是同一個(gè)對象,這就是單實(shí)例Bean,整個(gè)項(xiàng)目都會共享這一個(gè)bean對象。

      在Spring中,可以在元素的scope屬性里設(shè)置bean的作用域,以決定這個(gè)bean是單實(shí)例的還是多實(shí)例的。Scope屬性有四個(gè)參數(shù),具體的使用可以看下圖:

      1、單實(shí)例Bean聲明

      默認(rèn)情況下,Spring只為每個(gè)在IOC容器里聲明的bean創(chuàng)建唯一一個(gè)實(shí)例,整個(gè)IOC容器范圍內(nèi)都能共享該實(shí)例:所有后續(xù)的getBean()調(diào)用和bean引用都將返回這個(gè)唯一的bean實(shí)例。該作用域被稱為singleton,它是所有bean的默認(rèn)作用域。也就是單實(shí)例。

      為了驗(yàn)證這一說法,我們在IOC中創(chuàng)建一個(gè)單實(shí)例的bean,并且獲取該bean對象進(jìn)行對比:

      測試獲取到的單實(shí)例bean是否是同一個(gè):

      @Test public void test09() { // 單實(shí)例創(chuàng)建時(shí)創(chuàng)建的兩個(gè)bean相等 Book book03 = (Book)iocContext3.getBean("book02"); Book book04 = (Book)iocContext3.getBean("book02"); System.out.println(book03==book04); }

      得到的結(jié)果是true;

      2、多實(shí)例Bean聲明

      而既然存在單實(shí)例,那么就一定存在多實(shí)例。我們可以為bean對象的scope屬性設(shè)置prototype參數(shù),以表示該實(shí)例是多實(shí)例的,同時(shí)獲取IOC容器中的多實(shí)例bean,再將獲取到的多實(shí)例bean進(jìn)行對比,

      測試獲取到的多實(shí)例bean是否是同一個(gè):

      @Test public void test09() { // 多實(shí)例創(chuàng)建時(shí),創(chuàng)建的兩個(gè)bean對象不相等 Book book01 = (Book)iocContext3.getBean("book01"); Book book02 = (Book)iocContext3.getBean("book01"); System.out.println(book01==book02); }

      得到的結(jié)果是false

      這就說明了,通過多實(shí)例創(chuàng)建的bean對象是各不相同的。

      在這里需要注意:

      同時(shí)關(guān)于單實(shí)例和多實(shí)例bean的創(chuàng)建也有不同,當(dāng)bean的作用域?yàn)閱卫龝r(shí),Spring會在IOC容器對象創(chuàng)建時(shí)就創(chuàng)建bean的對象實(shí)例。而當(dāng)bean的作用域?yàn)閜rototype時(shí),IOC容器在獲取bean的實(shí)例時(shí)創(chuàng)建bean的實(shí)例對象。

      二、Bean的生命周期

      1、bean的初始和銷毀

      其實(shí)我們在IOC中創(chuàng)建的每一個(gè)bean對象都是有其特定的生命周期的,在Spring的IOC容器中可以管理bean的生命周期,Spring允許在bean生命周期內(nèi)特定的時(shí)間點(diǎn)執(zhí)行指定的任務(wù)。如在bean初始化時(shí)執(zhí)行的方法和bean被銷毀時(shí)執(zhí)行的方法。

      Spring IOC容器對bean的生命周期進(jìn)行管理的過程可以分為六步:

      通過構(gòu)造器或工廠方法創(chuàng)建bean實(shí)例

      為bean的屬性設(shè)置值和對其他bean的引用

      調(diào)用bean的初始化方法

      bean可以正常使用

      當(dāng)容器關(guān)閉時(shí),調(diào)用bean的銷毀方法

      那么關(guān)于bean的初始和銷毀時(shí)執(zhí)行的方法又該如何聲明呢?

      詳解Spring中Bean的作用域與生命周期

      首先我們應(yīng)該在bean類內(nèi)部添加初始和銷毀時(shí)執(zhí)行的方法。如下面這個(gè)javabean:

      package com.spring.beans; public class Book { private String bookName; private String author; /** * 初始化方法 * */ public void myInit() { System.out.println("book bean被創(chuàng)建"); } /** * 銷毀時(shí)方法 * */ public void myDestory() { System.out.println("book bean被銷毀"); } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } @Override public String toString() { return "Book [bookName=" + bookName + ", author=" + author + "]"; } }

      這時(shí)我們在配置bean時(shí),可以通過init-method和destroy-method 屬性為bean指定初始化和銷毀方法,

      這樣當(dāng)我們在通過IOC容器創(chuàng)建和銷毀bean對象時(shí)就會執(zhí)行相應(yīng)的方法,

      但是這里還是有一點(diǎn)需要注意:

      我們上面說了,單實(shí)例的bean和多實(shí)例的bean的創(chuàng)建時(shí)間是不同的,那么他們的初始方法和銷毀方法的執(zhí)行時(shí)間就稍稍有不同。

      單實(shí)例下 bean的生命周期

      容器啟動——>初始化方法——>(容器關(guān)閉)銷毀方法

      多實(shí)例下 bean的生命周期

      容器啟動——>調(diào)用bean——>初始化方法——>容器關(guān)閉(銷毀方法不執(zhí)行)

      2、bean的后置處理器

      什么是bean的后置處理器?bean后置處理器允許在調(diào)用初始化方法前后對bean進(jìn)行額外的處理

      bean后置處理器對IOC容器里的所有bean實(shí)例逐一處理,而非單一實(shí)例。

      其典型應(yīng)用是:檢查bean屬性的正確性或根據(jù)特定的標(biāo)準(zhǔn)更改bean的屬性。

      bean后置處理器使用時(shí)需要實(shí)現(xiàn)接口:

      org.springframework.beans.factory.config.BeanPostProcessor。

      在初始化方法被調(diào)用前后,Spring將把每個(gè)bean實(shí)例分別傳遞給上述接口的以下兩個(gè)方法:

      postProcessBeforeInitialization(Object, String)調(diào)用前

      postProcessAfterInitialization(Object, String)調(diào)用后

      如下是一個(gè)實(shí)現(xiàn)在該接口的后置處理器:

      package com.spring.beans; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; /** * 測試bean的后置處理器 * 在這里要注意一點(diǎn)是為了出現(xiàn)bean和beanName,而不是arg0、arg1,需要綁定相應(yīng)的源碼jar包 * */ public class MyBeanPostProcessor implements BeanPostProcessor{ /** * postProcessBeforeInitialization * 初始化方法執(zhí)行前執(zhí)行 * Object bean * String beanName xml容器中定義的bean名稱 * */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { // TODO Auto-generated method stub System.out.println("【"+ beanName+"】初始化方法執(zhí)行前..."); return bean; } /** * postProcessAfterInitialization * 初始化方法執(zhí)行后執(zhí)行 * Object bean * String beanName xml容器中定義的bean名稱 * */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { // TODO Auto-generated method stub System.out.println("【"+ beanName+"】初始化方法執(zhí)行后..."); return bean; } }

      將該后置處理器加入到IOC容器中:

      由于現(xiàn)在我們的bean對象是單實(shí)例的,所以容器運(yùn)行時(shí)就會直接創(chuàng)建bean對象,同時(shí)也會執(zhí)行該bean的后置處理器方法和初始化方法,在容器被銷毀時(shí)又會執(zhí)行銷毀方法。我們測試如下:

      //*************************bean生命周期***************** // 由于ApplicationContext是一個(gè)頂層接口,里面沒有銷毀方法close,所以需要使用它的子接口進(jìn)行接收 ConfigurableApplicationContext iocContext01 = new ClassPathXmlApplicationContext("ioc1.xml"); @Test public void test01() { iocContext01.getBean("book01"); iocContext01.close(); }

      運(yùn)行結(jié)果:

      總結(jié)一下后置處理器的執(zhí)行過程:

      通過構(gòu)造器或工廠方法創(chuàng)建bean實(shí)例

      為bean的屬性設(shè)置值和對其他bean的引用

      將bean實(shí)例傳遞給bean后置處理器的postProcessBeforeInitialization()方法

      調(diào)用bean的初始化方法

      將bean實(shí)例傳遞給bean后置處理器的postProcessAfterInitialization()方法

      bean可以使用了

      當(dāng)容器關(guān)閉時(shí)調(diào)用bean的銷毀方法

      所以添加bean后置處理器后bean的生命周期為:

      容器啟動——后置處理器的before...——>初始化方法——>后置處理器的after...———>(容器關(guān)閉)銷毀方法

      以上就是在SpringIOC中bean的作用域和生命周期的使用教程,有問題的小伙伴可以評論區(qū)或私信提出!

      ,以留備用!

      我是灰小猿!我們下期見!

      Spring

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:excel表格批量提取批注與刪除批注
      下一篇:在Word文檔中表格怎么讓文字環(huán)繞(word2010表格文字環(huán)繞方式)
      相關(guān)文章
      国产A在亚洲线播放| 中文字幕亚洲不卡在线亚瑟| 亚洲av无码成人黄网站在线观看| 亚洲精品国产精品乱码不卞| 偷自拍亚洲视频在线观看99| 国产亚洲欧美在线观看| 久久精品国产亚洲AV电影网| 337P日本欧洲亚洲大胆艺术图| 亚洲成a人片在线不卡一二三区| 亚洲丶国产丶欧美一区二区三区| 亚洲乱色伦图片区小说| 亚洲AV无码专区在线观看成人| 亚洲成av人无码亚洲成av人| 久久亚洲精品无码网站| 国产成人精品亚洲| 亚洲区小说区图片区| 精品国产日韩亚洲一区| 亚洲一区二区三区无码中文字幕| 亚洲人成色7777在线观看| 亚洲va久久久噜噜噜久久天堂| 亚洲AV乱码一区二区三区林ゆな| 亚洲视频在线观看一区| 亚洲网站在线免费观看| 亚洲人成在线免费观看| 伊人久久五月丁香综合中文亚洲 | 中文国产成人精品久久亚洲精品AⅤ无码精品| 国产亚洲男人的天堂在线观看| 亚洲国产综合人成综合网站| 超清首页国产亚洲丝袜| 亚洲成AV人片一区二区密柚| 亚洲尹人九九大色香蕉网站| 亚洲中文字幕在线无码一区二区| 亚洲人成网国产最新在线| 无码色偷偷亚洲国内自拍| 亚洲性日韩精品国产一区二区| 国产精品亚洲一区二区三区在线| 亚洲好看的理论片电影| 亚洲图片中文字幕| 亚洲欧美日韩一区二区三区在线| 国产亚洲漂亮白嫩美女在线| 亚洲性猛交XXXX|