**Bean的作用域**:
作用域:一般指的是對象或者變量之間的可見範圍。而在Spring容器中是指其創建的Bean對象相對於其他Bean對象的請求可見範圍。
Spring提供Singleton和prototype兩種基本作用域,另外提供Request、session、global、session三種web作用域;Spring還允許用戶制定自己的作用域。
基本的作用域
**一:Singleton:**指Singleton作用域的Bean只會在每個S平IOC容器中存在一個實例,而且其完整生命週期完全由Spring容器管理。對於所有獲取Bean的操作Spring容器將只返回同一個Bean。
GoF單例設計模式指“保證一個類僅有一個實例,並提供一個訪問它的全局訪問點”,介紹了兩種實現:通過在類上定義靜態屬性保持該實例和通過註冊表方式。
**1)通過在類上定義靜態屬性保持該實例**:一般指一個Java虛擬機 ClassLoader裝載的類只有一個實例,一般通過類靜態屬性保持該實例,這樣就造成需要單例的類都需要按照單例設計模式進行編碼;Spring沒采用這種方式,因爲該方式屬於侵入式設計;
package org.liang.test;
/**
* 單例類
*/
public class Singleton {
private String name;
private Singleton(){};
public static Singleton getInstance(){
return new Singleton();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class TsetSingleton{
public static void main(String [] args){
Singleton singleton = Singleton.getInstance();
singleton.setName("關羽");
System.out.println(singleton.getName());
}
}
**2) 通過註冊表方式:** 首先將需要單例的實例通過唯一鍵註冊到註冊表,然後通過鍵來獲取單例,讓我們直接看實現吧,注意本註冊表實現了Spring接口“SingletonBeanRegistry”,該接口定義了操作共享的單例對象,Spring容器實現將實現此接口;所以共享單例對象通過“registerSingleton”方法註冊,通過“getSingleton”方法獲取,消除了編程方式單例,注意在實現中不考慮併發。
package org.liang.test;
import org.liang.entity.Persion;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created by rcc on 2018/2/2.
*/
public class TestScope {
public static void main(String [] args){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
Persion persion = context.getBean(Persion.class);
Persion persion1 = context.getBean(Persion.class);
System.out.println(persion == persion1);
System.out.println("=======================================================");
Persion persion2 = new Persion();
Persion persion3 = new Persion();
System.out.println(persion2 == persion3);
System.out.println("=======================================================");
System.out.println(persion);
System.out.println(persion1);
/**
* 返回結果:
* true
*======================================================
* false
*
* 這就很奇怪了是不是,使用容器獲得的兩個所謂的新的對象居然是同一個對象,這和我們直接new兩個對象的結果剛好相反。
* 不過仔細想一想也不奇怪,既然對象是從Spring容器中獲取的,會不會是容器在對象創建的時候對對象進行了緩存呢?
*
* 基於這個猜想,我們將對象中的屬性打印出來:
*
* Persion{name='doudou', nickName='zhuzhu', age=18}
* Persion{name='doudou', nickName='zhuzhu', age=18}
* 結果居然一模一樣,返回的是同一個對象。
*
* 那麼這到底是什麼原因呢?
* <bean id="persion" class="org.liang.entity.Persion" scope="singleton">
<constructor-arg index="0" value="doudou"/>
<constructor-arg name="nickName" value="zhuzhu"/>
<constructor-arg type="java.lang.Integer" value="18"/>
</bean>
* 原因就是這個配置:scope="singleton" ,表示該對象是單例的,所以容器會緩存對象,每次獲取的對象都是同一個。
* 在Spring容器中如果沒指定作用域默認就是“singleton”。
*/
}
}
**二、prototype:即原型,**指每次向Spring容器請求獲取Bean都返回一個全新的Bean,相對於“singleton”來說就是不緩存Bean,每次都是一個根據Bean定義創建的全新Bean。
<bean id="user" class="org.liang.entity.User" scope="prototype">
<property name="name" value="張三"/>
<property name="gender" value="男"/>
<property name="age" value="18"/>
</bean>
========================================================================================
User user = (User) context.getBean("user");
User user1 = (User) context.getBean("user");
System.out.println(user == user1);
/**
返回結果:
* =======================================================
false :每次獲取的都是全新的對象
*/
**Web應用中的作用域:**
在Web應用中,我們可能需要將數據存儲到request、session、global session。因此Spring提供了三種Web作用域:request、session、globalSession。
一、request作用域:表示每個請求需要容器創建一個全新Bean。比如提交表單的數據必須是對每次請求新建一個Bean來保持這些表單數據,請求結束釋放這些數據。
二、session作用域:表示每個會話需要容器創建一個全新Bean。比如對於每個用戶一般會有一個會話,該用戶的用戶信息需要存儲到會話中,此時可以將該Bean配置爲web作用域。
三、globalSession:類似於session作用域,只是其用於portlet環境的web應用。如果在非portlet環境將視爲session作用域。
配置方式和基本的作用域相同,只是必須要有web環境支持,並配置相應的容器監聽器或攔截器從而能應用這些作用域,我們會在集成web時講解具體使用,大家只需要知道有這些作用域就可以了。
Spring學習--Bean的作用域
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.