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

Spring Bean Scope 有狀態(tài)的Bean與無(wú)狀態(tài)的Bean

 更新時(shí)間:2022年01月20日 10:20:43   作者:cs408 ?  
這篇文章主要介紹了Spring Bean Scope 有狀態(tài)的Bean與無(wú)狀態(tài)的Bean,每個(gè)用戶有自己特有的一個(gè)實(shí)例,在用戶的生存期內(nèi),bean保持了用戶的信息,下面來(lái)了解有狀態(tài)和無(wú)狀態(tài)的區(qū)別吧

有狀態(tài)會(huì)話bean:每個(gè)用戶有自己特有的一個(gè)實(shí)例,在用戶的生存期內(nèi),bean保持了用戶的信息,即“有狀態(tài)”;一旦用戶滅亡(調(diào)用結(jié)束或?qū)嵗Y(jié)束),bean的生命期也告結(jié)束。即每個(gè)用戶最初都會(huì)得到一個(gè)初始的bean。   
    
  無(wú)狀態(tài)會(huì)話bean:bean一旦實(shí)例化就被加進(jìn)會(huì)話池中,各個(gè)用戶都可以共用。即使用戶已經(jīng)消亡,bean   的生命期也不一定結(jié)束,它可能依然存在于會(huì)話池中,供其他用戶調(diào)用。由于沒(méi)有特定的用戶,那么也就不能保持某一用戶的狀態(tài),所以叫無(wú)狀態(tài)bean。但無(wú)狀態(tài)會(huì)話bean   并非沒(méi)有狀態(tài),如果它有自己的屬性(變量),那么這些變量就會(huì)受到所有調(diào)用它的用戶的影響,這是在實(shí)際應(yīng)用中必須注意的。

在Spring的Bean配置中,存在這樣兩種情況:

<bean id="testManager" class="com.sw.TestManagerImpl" scope="singleton" /> ?
??
?<bean id="testManager" class="com.sw.TestManagerImpl" scope="prototype" /> ?

當(dāng)然,scope的值不止這兩種,還包括了request,session 等。但用的最多的還是singleton單態(tài),prototype多態(tài)。

singleton表示該bean全局只有一個(gè)實(shí)例,Spring中bean的scope默認(rèn)也是singleton.

prototype表示該bean在每次被注入的時(shí)候,都要重新創(chuàng)建一個(gè)實(shí)例,這種情況適用于有狀態(tài)的Bean.

對(duì)于SSH架構(gòu)的系統(tǒng),很少關(guān)心這方面,因?yàn)槲覀冇玫降囊话愣际莝ingleton. Bean的注入由Spring管理。

對(duì)于有狀態(tài)的Bean呢?

下面是一個(gè)有狀態(tài)的Bean:

package com.sw; ?
??
public class TestManagerImpl implements TestManager{ ?
? ? private User user; ? ?
??
? ? public void deleteUser(User e) throws Exception { ?
? ? ? ? user = e ; ? ? ? ? ? //1 ?
? ? ? ? prepareData(e); ?
? ? } ?
??
? ? public void prepareData(User e) throws Exception { ?
? ? ? ? user = getUserByID(e.getId()); ? ? ? ? ? ?//2 ?
? ? ? ? ..... ?
? ? ? ? //使用user.getId(); ? ? ? ? ? ? ? ? ? ? ? //3 ?
? ? ? ? ..... ?
? ? ? ? ..... ?
? ? } ? ??
} ?

如果該Bean配置為singleton,會(huì)出現(xiàn)什么樣的狀況呢?

如果有2個(gè)用戶訪問(wèn),都調(diào)用到了該Bean.

假定為user1,user2

當(dāng)user1 調(diào)用到程序中的1步驟的時(shí)候,該Bean的私有變量user被付值為user1

當(dāng)user1的程序走到2步驟的時(shí)候,該Bean的私有變量user被重新付值為user1_create

理想的狀況,當(dāng)user1走到3步驟的時(shí)候,私有變量user應(yīng)該為user1_create;

但如果在user1調(diào)用到3步驟之前,user2開始運(yùn)行到了1步驟了,由于單態(tài)的資源共享,則私有變量user被修改為user2

這種情況下,user1的步驟3用到的user.getId()實(shí)際用到是user2的對(duì)象。(我的理解是配置成singleton會(huì)造成資源混亂問(wèn)題-對(duì)于有狀態(tài)的bean)

而如果是prototype的話,就不會(huì)出現(xiàn)資源共享的問(wèn)題。(即不會(huì)出現(xiàn)線程安全的問(wèn)題)

對(duì)于SSH來(lái)說(shuō),Bean的配置是沒(méi)錯(cuò)的,配置為singleton ;

實(shí)際應(yīng)該是這個(gè)例子不應(yīng)該用私有變量,這樣就使得這個(gè)Bean由無(wú)狀態(tài)變成了有狀態(tài)Bean.

還是應(yīng)該盡量使用無(wú)狀態(tài)Bean.如果在程序中出現(xiàn)私有變量(該bean會(huì)變?yōu)橛袪顟B(tài)的,一旦在其他線程中發(fā)生改變,就會(huì)產(chǎn)生線程不安全),解決方案就是盡量替換為方法中的參數(shù)。
對(duì)于每個(gè)訪問(wèn)私有變量的方法增加變量傳入(參數(shù)傳入)或者通過(guò)ThreadLocal來(lái)獲取也是不錯(cuò)的方法。(重點(diǎn)解決方案,可以防止多線程帶來(lái)的不安全問(wèn)題)

真正出現(xiàn)上面代碼問(wèn)題的也是少數(shù),出現(xiàn)的時(shí)候,一般是為了圖方便,使用了一個(gè)很多方法都要用到的變量(變量在傳遞過(guò)程中發(fā)生改變,就會(huì)產(chǎn)生多線程不安全問(wèn)題)。如果變量都需要用參數(shù)的方式傳遞多麻煩呀,這樣私有變量多好,不用參數(shù)那樣丑陋。但是丑陋并不代表不好,以對(duì)的,自己習(xí)慣的方式編程,才能盡量避免問(wèn)題的發(fā)生。

引申:

Spring中的有狀態(tài)(Stateful)和無(wú)狀態(tài)(Stateless) (web中的并發(fā)通過(guò)單例可以避免)

  • 1.通過(guò)上面的分析,相信大家已經(jīng)對(duì)有狀態(tài)和無(wú)狀態(tài)有了一定的理解。無(wú)狀態(tài)的Bean適合用不變模式,技術(shù)就是單例模式,這樣可以共享實(shí)例,提高性能。有狀態(tài)的Bean,多線程環(huán)境下不安全,那么適合用Prototype原型模式(解決多線程問(wèn)題)。Prototype: 每次對(duì)bean的請(qǐng)求都會(huì)創(chuàng)建一個(gè)新的bean實(shí)例。 
  • 2.默認(rèn)情況下,從Spring bean工廠所取得的實(shí)例為singleton(scope屬性為singleton),容器只存在一個(gè)共享的bean實(shí)例。 
  • 3.理解了兩者的關(guān)系,那么scope選擇的原則就很容易了:有狀態(tài)的bean都使用prototype作用域,而對(duì)無(wú)狀態(tài)的bean則應(yīng)該使用singleton作用域。 
  • 4.如Service層、Dao層用默認(rèn)singleton就行,雖然Service類也有dao這樣的屬性,但dao這些類都是沒(méi)有狀態(tài)信息的,也就是相當(dāng)于不變(immutable)類,所以不影響。Struts2中的Action因?yàn)闀?huì)有User、BizEntity這樣的實(shí)例對(duì)象,是有狀態(tài)信息的,在多線程環(huán)境下是不安全的,所以Struts2默認(rèn)的實(shí)現(xiàn)是Prototype模式。在Spring中,Struts2的Action中,scope要配成prototype作用域。 

Servlet、Struts中的有狀態(tài)和無(wú)狀態(tài): 

1.Servlet體系結(jié)構(gòu)是建立在Java多線程機(jī)制之上的,它的生命周期是由Web 容器負(fù)責(zé)的。一個(gè)Servlet類在Application中只有一個(gè)實(shí)例存在,也就是有多個(gè)線程在使用這個(gè)實(shí)例。這是單例模式的應(yīng)用。無(wú)狀態(tài)的單例是線程安全的,但我們?nèi)绻赟ervlet里用了實(shí)例變量(私有變量),那么就變成有狀態(tài)了,是非線程安全的。如下面的用法就是不安全的,因?yàn)閡ser,out都是有狀態(tài)信息的。 

/**?
?* 非線程安全的Servlet。?
?* @author Peter Wei?
?*?
?*/ ?
public class UnSafeServlet HttpServlet{ ?
? ? ??
? ? User user; ?
? ? PrintWriter out; ?
? ? ??
? ? public void doGet (HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{ ?
? ? ? ? //do something... ?
? ? } ?
} ?

Out,Request,Response,Session,Config,Page,PageContext是線程安全的,Application在整個(gè)系統(tǒng)內(nèi)被使用,所以不是線程安全的. 

2.Struts1也是基于單例模式實(shí)現(xiàn),也就是只有一個(gè)Action實(shí)例供多線程使用。默認(rèn)的模式是前臺(tái)頁(yè)面數(shù)據(jù)通過(guò)actionForm傳入,在action中的excute方法接收,這樣action是無(wú)狀態(tài)的,所以一般情況下Strunts1是線程安全的。如果Action中用了實(shí)例變量,那么就變成有狀態(tài)了,同樣是非線程安全的。像下面這樣就是線程不安全的。 

/**?
?* 非線程安全的Struts1示例?
?* ?
?* @author Peter Wei?
?* ?
?*/ ?
public class UnSafeAction1 extends Action { ?
??
? ? // 因?yàn)镾truts1是單例實(shí)現(xiàn),有狀態(tài)情況下,對(duì)象引用是非線程安全的 ?
? ? User user; ?
??
? ? public void execute() { ?
? ? ? ? // do something... ?
? ? } ?
??
? ? public User getUser() { ?
? ? ? ? return user; ?
? ? } ?
??
? ? public void setUser(User user) { ?
? ? ? ? this.user = user; ?
? ? } ?
} ? ?

3.Struts2默認(rèn)的實(shí)現(xiàn)是Prototype模式。也就是每個(gè)請(qǐng)求都新生成一個(gè)Action實(shí)例,所以不存在線程安全問(wèn)題。需要注意的是,如果由Spring管理action的生命周期, scope要配成prototype作用域。 

4.如何解決Servlet和Struts1的線程安全問(wèn)題,當(dāng)我們能比較好的理解有狀態(tài)和無(wú)狀態(tài)的原理,自然很容易得出結(jié)論: 不要使用有狀態(tài)的bean,也就是不要用實(shí)例變量(私有變量) 。如果用有狀態(tài)的bean,就要用prototype模式,每次在注入的時(shí)候就重新創(chuàng)建一個(gè)bean,在多線程中互不影響。Struts1 user guide里有: Only Use Local Variables - The most important principle that aids in thread-safe coding is to use only local variables, not instance variables , in your Action class. 

總結(jié):  

Stateless無(wú)狀態(tài)用單例Singleton模式,Stateful有狀態(tài)就用原型Prototype模式。  
Stateful 有狀態(tài)是多線程編碼的天敵,所以在開發(fā)中盡量用Stateless無(wú)狀態(tài),無(wú)狀態(tài)是不變(immutable)模式的應(yīng)用,有很多優(yōu)點(diǎn):不用管線程和同步的問(wèn)題 ,如果值是不可變的,程序不用擔(dān)心多個(gè)線程改變共享狀態(tài),所以可以避免線程競(jìng)爭(zhēng)的bugs. 因?yàn)闆](méi)有競(jìng)爭(zhēng),就不用用locks等機(jī)制,所以無(wú)狀態(tài)的不變機(jī)制,也可以避免產(chǎn)生死鎖現(xiàn)象。 

到此這篇關(guān)于Spring Bean Scope 有狀態(tài)的Bean與無(wú)狀態(tài)的Bean的文章就介紹到這了,更多相關(guān) 有狀態(tài)的Bean與無(wú)狀態(tài)的Bean內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Javafx利用fxml變換場(chǎng)景的實(shí)現(xiàn)示例

    Javafx利用fxml變換場(chǎng)景的實(shí)現(xiàn)示例

    本文主要介紹了Javafx利用fxml變換場(chǎng)景的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-07-07
  • mybatis中oracle實(shí)現(xiàn)分頁(yè)效果實(shí)例代碼

    mybatis中oracle實(shí)現(xiàn)分頁(yè)效果實(shí)例代碼

    實(shí)現(xiàn)分頁(yè)的方式有很多,但常用的是通過(guò)SQL來(lái)顯示分頁(yè)。這篇文章主要介紹了mybatis中oracle實(shí)現(xiàn)分頁(yè)效果實(shí)例代碼,有興趣的可以了解一下。
    2017-04-04
  • IDEA最新激活碼2021(IDEA2020.3.2最新永久激活方法)

    IDEA最新激活碼2021(IDEA2020.3.2最新永久激活方法)

    這篇文章主要介紹了IDEA最新激活碼2021(IDEA2020.3.2最新永久激活方法),本文通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • SpringCloud消息總線Bus配置中心實(shí)現(xiàn)過(guò)程解析

    SpringCloud消息總線Bus配置中心實(shí)現(xiàn)過(guò)程解析

    這篇文章主要介紹了SpringCloud消息總線Bus配置中心實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • 關(guān)于Maven parent.relativePath說(shuō)明

    關(guān)于Maven parent.relativePath說(shuō)明

    Maven中的relativePath用于指定父項(xiàng)目pom.xml的相對(duì)路徑,默認(rèn)值為../pom.xml,這個(gè)配置幫助Maven在構(gòu)建時(shí)定位父模塊的位置,確保模塊間的依賴關(guān)系正確,relativePath可以指向本地或遠(yuǎn)程倉(cāng)庫(kù)中的父項(xiàng)目,如果不需要尋找父項(xiàng)目,可以將其設(shè)置為空
    2024-09-09
  • Java線程生命周期的終止與復(fù)位

    Java線程生命周期的終止與復(fù)位

    這篇文章主要介紹了Java線程生命周期的終止與復(fù)位,Java的線程狀態(tài)描述放在Thread類里面的枚舉類State中.總共包含了6中狀態(tài),具體詳情需要的小伙伴可以參考一下文章描述
    2022-07-07
  • Spring @Component自定義注解實(shí)現(xiàn)詳解

    Spring @Component自定義注解實(shí)現(xiàn)詳解

    @Component是一個(gè)元注解,意思是可以注解其他類注解,如@Controller @Service @Repository @Aspect。官方的原話是:帶此注解的類看為組件,當(dāng)使用基于注解的配置和類路徑掃描的時(shí)候,這些類就會(huì)被實(shí)例化
    2022-09-09
  • 基于SpringBoot實(shí)現(xiàn)Web應(yīng)用的登錄與退出功能

    基于SpringBoot實(shí)現(xiàn)Web應(yīng)用的登錄與退出功能

    登錄與退出功能作為 Web 應(yīng)用中的基礎(chǔ)且重要的組成部分,直接關(guān)系到用戶的安全和隱私保護(hù),所以本文給大家介紹了基于SpringBoot實(shí)現(xiàn)Web應(yīng)用的登錄與退出功能,文中有詳細(xì)的代碼供大家參考,需要的朋友可以參考下
    2024-04-04
  • Spring+quartz實(shí)現(xiàn)定時(shí)發(fā)送郵件功能實(shí)例

    Spring+quartz實(shí)現(xiàn)定時(shí)發(fā)送郵件功能實(shí)例

    spring提供的定時(shí)發(fā)送郵件功能一直深受廣大web開發(fā)者的喜愛(ài),這篇文章主要介紹了Spring+quartz實(shí)現(xiàn)定時(shí)發(fā)送郵件功能實(shí)例,有興趣的可以了解一下。
    2017-03-03
  • Spring MVC4.1服務(wù)器端推送實(shí)現(xiàn)過(guò)程解析

    Spring MVC4.1服務(wù)器端推送實(shí)現(xiàn)過(guò)程解析

    這篇文章主要介紹了Spring MVC4.1服務(wù)器端推送實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11

最新評(píng)論

通榆县| 馆陶县| 西昌市| 鄂托克前旗| 香格里拉县| 磐安县| 荔波县| 平乐县| 新泰市| 岳普湖县| 广平县| 扎兰屯市| 大荔县| 新安县| 礼泉县| 府谷县| 盐津县| 东辽县| 朔州市| 庆城县| 阳朔县| 南城县| 化德县| 衡东县| 色达县| 颍上县| 民丰县| 井研县| 青川县| 鹤峰县| 桃江县| 盐亭县| 华安县| 石泉县| 永平县| 新宁县| 太康县| 修武县| 岳阳市| 五华县| 凤庆县|