最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2021年08月03日 10:38:47   作者:灰小猿  
這篇文章主要給大家介紹了Spring中Bean的生命周期和作用域及實(shí)現(xiàn)方式的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來(lái)一起看看吧

一、Bean的作用域

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

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

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

在Spring中,可以在<bean>元素的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)證這一說(shuō)法,我們?cè)贗OC中創(chuàng)建一個(gè)單實(shí)例的bean,并且獲取該bean對(duì)象進(jìn)行對(duì)比:

<!-- singleton單實(shí)例bean
  1、在容器創(chuàng)建時(shí)被創(chuàng)建
  2、只有一個(gè)實(shí)例
  -->
<bean id="book02" class="com.spring.beans.Book" scope="singleton"></bean>

測(cè)試獲取到的單實(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對(duì)象的scope屬性設(shè)置prototype參數(shù),以表示該實(shí)例是多實(shí)例的,同時(shí)獲取IOC容器中的多實(shí)例bean,再將獲取到的多實(shí)例bean進(jìn)行對(duì)比,

<!-- prototype多實(shí)例bean
1、在容器創(chuàng)建時(shí)不會(huì)被創(chuàng)建,
2、只有在被調(diào)用的時(shí)候才會(huì)被創(chuàng)建
3、可以存在多個(gè)實(shí)例
 -->
<bean id="book01" class="com.spring.beans.Book" scope="prototype"></bean>

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

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

得到的結(jié)果是false

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

在這里需要注意:

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

二、Bean的生命周期

1、bean的初始和銷毀

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

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

  • 通過(guò)構(gòu)造器或工廠方法創(chuàng)建bean實(shí)例
  • 為bean的屬性設(shè)置值和對(duì)其他bean的引用
  • 調(diào)用bean的初始化方法
  • bean可以正常使用
  • 當(dāng)容器關(guān)閉時(shí),調(diào)用bean的銷毀方法

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

首先我們應(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í)我們?cè)谂渲胋ean時(shí),可以通過(guò)init-method和destroy-method 屬性為bean指定初始化和銷毀方法,

<!-- 設(shè)置bean的生命周期
destory-method:結(jié)束調(diào)用的方法
init-method:起始時(shí)調(diào)用的方法
 -->
<bean id="book01" class="com.spring.beans.Book" destroy-method="myDestory" init-method="myInit"></bean>

這樣當(dāng)我們?cè)谕ㄟ^(guò)IOC容器創(chuàng)建和銷毀bean對(duì)象時(shí)就會(huì)執(zhí)行相應(yīng)的方法,

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

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

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

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

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

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

2、bean的后置處理器

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

bean后置處理器對(duì)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;
/**
 * 測(cè)試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容器中:

<!-- 測(cè)試bean的后置處理器 -->
<bean id="beanPostProcessor" class="com.spring.beans.MyBeanPostProcessor"></bean>

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

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

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

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

通過(guò)構(gòu)造器或工廠方法創(chuàng)建bean實(shí)例為bean的屬性設(shè)置值和對(duì)其他bean的引用將bean實(shí)例傳遞給bean后置處理器的postProcessBeforeInitialization()方法調(diào)用bean的初始化方法將bean實(shí)例傳遞給bean后置處理器的postProcessAfterInitialization()方法bean可以使用了當(dāng)容器關(guān)閉時(shí)調(diào)用bean的銷毀方法

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

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

總結(jié)

本篇文章就到這里了,希望能給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • PL/SQL實(shí)現(xiàn)JAVA中的split()方法的例子

    PL/SQL實(shí)現(xiàn)JAVA中的split()方法的例子

    這篇文章主要介紹了PL/SQL實(shí)現(xiàn)JAVA中的split()方法的例子的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • 一文詳解Springboot集成mybatis-plus

    一文詳解Springboot集成mybatis-plus

    這篇文章主要介紹了Mybatis-Plus與SpringBoot整合,并在項(xiàng)目中實(shí)戰(zhàn)運(yùn)用,列舉其增刪改查的使用方式,對(duì)學(xué)習(xí)或工作有一定的幫助,需要的小伙伴可以參考閱讀
    2023-04-04
  • Java實(shí)現(xiàn)http請(qǐng)求文件流對(duì)帶寬限速獲取md5值

    Java實(shí)現(xiàn)http請(qǐng)求文件流對(duì)帶寬限速獲取md5值

    文章介紹了如何在進(jìn)行HTTP請(qǐng)求下載大數(shù)據(jù)時(shí)處理帶寬限制和并發(fā)問(wèn)題,通過(guò)使用緩沖區(qū)和限速邏輯,可以有效控制下載速度,避免掉包和數(shù)據(jù)丟失,核心公式基于帶寬和已下載字節(jié)數(shù)計(jì)算預(yù)期耗時(shí),并通過(guò)Thread.sleep()進(jìn)行動(dòng)態(tài)休眠補(bǔ)償,感興趣的朋友一起看看吧
    2025-02-02
  • @RequestBody 部分屬性沒(méi)有轉(zhuǎn)化成功的處理

    @RequestBody 部分屬性沒(méi)有轉(zhuǎn)化成功的處理

    這篇文章主要介紹了@RequestBody 部分屬性沒(méi)有轉(zhuǎn)化成功的處理方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java實(shí)現(xiàn)七牛云文件圖片上傳下載

    Java實(shí)現(xiàn)七牛云文件圖片上傳下載

    本文主要介紹了Java實(shí)現(xiàn)七牛云文件圖片上傳下載,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • springsecurity基于token的認(rèn)證方式

    springsecurity基于token的認(rèn)證方式

    本文主要介紹了springsecurity基于token的認(rèn)證方式,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 解決mybatisPlus null 值更新的問(wèn)題

    解決mybatisPlus null 值更新的問(wèn)題

    這篇文章主要介紹了解決mybatisPlus null 值更新的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • Java8新特性之重復(fù)注解與類型注解詳解

    Java8新特性之重復(fù)注解與類型注解詳解

    這篇文章主要使介紹了Java8新特性重復(fù)注解與類型注解,文章還介紹了JDK5中的注解與之對(duì)比,感興趣的朋友可以參考下面具體文章內(nèi)容
    2021-09-09
  • Java中的線程池ThreadPoolExecutor深入解析

    Java中的線程池ThreadPoolExecutor深入解析

    這篇文章主要介紹了Java中的線程池ThreadPoolExecutor深入解析,線程池,thread pool,是一種線程使用模式,線程池維護(hù)著多個(gè)線程,等待著監(jiān)督管理者分配可并發(fā)執(zhí)行的任務(wù),需要的朋友可以參考下
    2023-11-11
  • java題解LeetCode20.有效的括號(hào)

    java題解LeetCode20.有效的括號(hào)

    這篇文章主要為大家介紹了java題解LeetCode20.有效的括號(hào)示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10

最新評(píng)論

康保县| 马龙县| 合肥市| 新闻| 隆德县| 彰化县| 东阿县| 林芝县| 泉州市| 昭平县| 襄垣县| 天镇县| 阜南县| 河间市| 广宁县| 南城县| 宜章县| 莱西市| 梅河口市| 鹤岗市| 台中县| 马关县| 文昌市| 象山县| 太仓市| 个旧市| 公主岭市| 桐庐县| 翁源县| 高唐县| 塘沽区| 玛纳斯县| 隆安县| 浮山县| 达日县| 桂东县| 福安市| 榆中县| 榆树市| 普宁市| 仁怀市|