作用域通俗一點(diǎn)------>表示:有效范圍帝蒿。
Spring Bean的有效范圍驮宴,在XML中用scope
定義
<bean id="BeanScopeTest" class="com.zing.test.bean.BeanScopeTest" scope="singleton"/>
SpringMVC 中定義了singleton
紧憾,prototype
基本作用域和三個(gè)web作用域
先解釋基本作用域墩虹,并且允許用戶(hù)自己定義作用域
基本作用域
-
singleton
作用域的Bean只會(huì)在每個(gè)Spring IoC容器中存在一個(gè)實(shí)例,而且其完整生命周期完全由Spring容器管理顷歌。對(duì)于所有獲取該Bean的操作Spring容器將只返回同一個(gè)Bean。
單例模式:就是私有化構(gòu)造函數(shù)幔睬,通過(guò)唯一的方法獲取對(duì)象眯漩,并且每次獲取為同一對(duì)象
public class Singleton {
/*1.私有化構(gòu)造函數(shù)*/
private Singleton() {}
//2.單例緩存者,惰性初始化溪窒,第一次使用時(shí)初始化
private static class InstanceHolder {
private static final Singleton INSTANCE = new Singleton();
}
//3.提供全局訪問(wèn)點(diǎn)
public static Singleton getInstance() {
return InstanceHolder.INSTANCE;
}
}
以上就實(shí)現(xiàn)了一個(gè)單例模型
Spring把模型通過(guò)注冊(cè)表的方式坤塞,將Bean緩存起來(lái)冯勉,先將Bean通過(guò)唯一鍵注冊(cè)到表中,再通過(guò)鍵來(lái)獲取他們摹芙,Spring的單例模式是通過(guò)注冊(cè)表實(shí)現(xiàn)的灼狰,而非代碼式單例模式,所以是非侵入式的浮禾。
在Spring中交胚,Bean在沒(méi)有指定作用域的時(shí)候,默認(rèn)是單例模式的盈电。
-
prototype
原型模式蝴簇,每次都是獲取新的對(duì)象,跟單例模式不一樣匆帚,Spring不對(duì)prototype模式的Bean進(jìn)行緩存
Web應(yīng)用中的作用域
Spring提供了3種在Web中的作用域熬词,分別在request
、session
吸重、globalSession
互拾。這些作用域的有效范圍分別如下
request
每一次HTTP請(qǐng)求都會(huì)產(chǎn)生一個(gè)新的bean,這個(gè)bean僅在當(dāng)前request內(nèi)有效session
每一次HTTP請(qǐng)求都會(huì)產(chǎn)生一個(gè)新的bean嚎幸,同時(shí)該bean僅在當(dāng)前session內(nèi)有效global session
全局session有效颜矿,這個(gè)是針對(duì)portlet的web應(yīng)用的,具體可以看看Portlet是如何定義了全局Session的嫉晶。這個(gè)有效范圍是全局portlet Session的生命周期范圍內(nèi)骑疆,如果不是portlet的web應(yīng)用,那么這個(gè)等同于session
作用域替废。
利用注解定義作用域
很簡(jiǎn)單箍铭,例子如下
@Scope("prototype")
@Component("bean")
public class BeanAnnotation {
public void say(String arg) {
System.out.println(arg);
}
}
自定義bean裝配作用域
在2.0之后,Spring支持自己定義作用域了(不能覆蓋singleton和prototype這兩個(gè)現(xiàn)有的作用域)只要實(shí)現(xiàn)Scope接口就可以舶担。
我們建立一個(gè)線程的scope坡疼,該scope在表示一個(gè)線程中有效,代碼如下:
import org.springframework.beans.factory.config.Scope;
public class MyScope implements Scope {
private final ThreadLocal threadScope = new ThreadLocal() {
protected Object initialValue() {
return new HashMap();
}
};
public Object get(String name, ObjectFactory objectFactory) {
Map scope = (Map) threadScope.get();
Object object = scope.get(name);
if(object==null) {
object = objectFactory.getObject();
scope.put(name, object);
}
return object;
}
public Object remove(String name) {
Map scope = (Map) threadScope.get();
return scope.remove(name);
}
publicvoid registerDestructionCallback(String name, Runnable callback) {
}
public String getConversationId() {
// TODO Auto-generated method stub
return null;
}
}