欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

一、Bean的作用域

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

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

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

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

1、單實例Bean聲明

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

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

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

測試獲取到的單實例bean是否是同一個:

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

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

2、多實例Bean聲明

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

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

測試獲取到的多實例bean是否是同一個:

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

得到的結(jié)果是false

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

在這里需要注意:

同時關(guān)于單實例和多實例bean的創(chuàng)建也有不同,當bean的作用域為單例時,Spring會在IOC容器對象創(chuàng)建時就創(chuàng)建bean的對象實例。而當bean的作用域為prototype時,IOC容器在獲取bean的實例時創(chuàng)建bean的實例對象。

二、Bean的生命周期

1、bean的初始和銷毀

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

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

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

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

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

package com.spring.beans;
public class Book {
	private String bookName;
	private String author;
	/**
	 * 初始化方法
	 * */
	public void myInit() {
		System.out.println("book bean被創(chuàng)建");
	}
	/**
	 * 銷毀時方法
	 * */
	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 + "]";
	}
	
}

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

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

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

但是這里還是有一點需要注意:

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

單實例下 bean的生命周期

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

多實例下 bean的生命周期

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

2、bean的后置處理器

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

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

其典型應用是:檢查bean屬性的正確性或根據(jù)特定的標準更改bean的屬性。

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

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

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

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

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

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

package com.spring.beans;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
 * 測試bean的后置處理器
 * 在這里要注意一點是為了出現(xiàn)bean和beanName,而不是arg0、arg1,需要綁定相應的源碼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容器中:

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

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

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

運行結(jié)果:

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

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

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

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

總結(jié)

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

相關(guān)文章

  • SpringBoot整合ElasticSearch實踐

    SpringBoot整合ElasticSearch實踐

    本篇文章主要介紹了SpringBoot整合ElasticSearch實踐,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • SpringMVC框架使用jackson封裝數(shù)據(jù)過程中遇到的問題及解決

    SpringMVC框架使用jackson封裝數(shù)據(jù)過程中遇到的問題及解決

    這篇文章主要介紹了SpringMVC框架使用jackson封裝數(shù)據(jù)過程中遇到的問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • 重新認識Java的System.in

    重新認識Java的System.in

    今天小編就為大家分享一篇關(guān)于重新認識Java的System.in,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • Spring bean為什么默認是單例

    Spring bean為什么默認是單例

    這篇文章主要介紹了Spring bean為什么默認是單例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • Java Websocket Canvas實現(xiàn)井字棋網(wǎng)絡(luò)游戲

    Java Websocket Canvas實現(xiàn)井字棋網(wǎng)絡(luò)游戲

    這篇文章主要介紹了Java Websocket Canvas實現(xiàn)井字棋網(wǎng)絡(luò)游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • mybatis多對多關(guān)聯(lián)實戰(zhàn)教程(推薦)

    mybatis多對多關(guān)聯(lián)實戰(zhàn)教程(推薦)

    下面小編就為大家?guī)硪黄猰ybatis多對多關(guān)聯(lián)實戰(zhàn)教程(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • JavaSE實戰(zhàn)之酒店訂房系統(tǒng)的實現(xiàn)

    JavaSE實戰(zhàn)之酒店訂房系統(tǒng)的實現(xiàn)

    這篇文章主要為大家詳細介紹了如何利用JavaSE實現(xiàn)酒店訂房系統(tǒng),文中的示例代碼講解詳細,對我們學習JavaSE開發(fā)有一定的幫助,需要的可以參考一下
    2022-07-07
  • Java Kafka分區(qū)發(fā)送及消費實戰(zhàn)

    Java Kafka分區(qū)發(fā)送及消費實戰(zhàn)

    本文主要介紹了Kafka分區(qū)發(fā)送及消費實戰(zhàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • Java零基礎(chǔ)教程之Windows下安裝 JDK的方法圖解

    Java零基礎(chǔ)教程之Windows下安裝 JDK的方法圖解

    這篇文章主要介紹了Java零基礎(chǔ)教程之Windows下安裝 JDK的方法圖解,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下
    2016-09-09
  • JFinal 調(diào)用存儲過程的步驟

    JFinal 調(diào)用存儲過程的步驟

    這篇文章主要介紹了JFinal 調(diào)用存儲過程的步驟,幫助大家更好的理解和學習使用JFinal,感興趣的朋友可以了解下
    2021-03-03

最新評論