隨筆-42  評(píng)論-349  文章-4  trackbacks-0
          By:殘夢(mèng)追月

          (殘夢(mèng)追月原創(chuàng),轉(zhuǎn)載請(qǐng)注明)

          jsp中,使用jsp標(biāo)簽來(lái)引用JavaBean,可以通過(guò)其scope屬性的值來(lái)確定該標(biāo)簽引用JavaBean的作用范圍。在Spring IOC容器中,由它管理的Java Bean也具有作用范圍。

          Spring1.x版本中,標(biāo)簽有一個(gè)屬性singleton,取值為布爾類型。如果將其設(shè)置為true,那么容器之中只存在一個(gè)該bean的共享實(shí)例,當(dāng)其他的任何Bean依賴該bean時(shí),只要請(qǐng)求的id與該beanid相同,容器就將該bean的實(shí)例注入到請(qǐng)求的bean中。換言之,Spring IoC容器只是創(chuàng)建該bean的一個(gè)唯一實(shí)例,并把它存存貯在容器的單例緩存中,在需要時(shí)才將其取出。這樣的受管bean稱之為“單例bean”。

          如果設(shè)置為false,那么每當(dāng)其他bean依賴此bean時(shí),容器則會(huì)重新實(shí)例化一個(gè)該bean對(duì)象,為其注入。

          需要注意的是:
          ??? 1、在下面的例子中,如果把computer1computer2兩個(gè)受管bean都設(shè)置成單例beanSpring IoC容器則分別實(shí)例化兩個(gè)bean,把它們作為兩個(gè)不同的bean對(duì)待,盡管他們的類相同。
          ??
          1?<bean?id="computer1"?class="ioc.test.Computer"?scope="singleton"/></bean>
          2?<bean?id="computer2"class="ioc.test.Computer"?scope="singleton"/></bean>

          2、一般來(lái)說(shuō),對(duì)于無(wú)狀態(tài)的bean使用單例模式,對(duì)于有狀態(tài)的bean使用prototype模式。

          3、Spring IoC容器不會(huì)維護(hù)prototype類型的bean的整個(gè)聲明周期,容器在實(shí)例化、配置、注入之后就把它扔給調(diào)用者,然后就不管了。

          4、如果一個(gè)單例bean computer引用了一個(gè)prototype類型的bean host,由于單例bean只初始化一次,所以不能保證每次調(diào)用computer時(shí)host都是最新的。解決辦法是使用lookup方法注入。

          到了Spring2.0時(shí)代,scope屬性代替了原來(lái)的的singleton屬性,scope提供了更多的選項(xiàng),從而可以更加靈活的配置bean的作用范圍。Spring2.0中,scope屬性有如下可能的取值,說(shuō)明如下:1、 singleton,即單例bean,和1.xsingleton=”true”相同。

          2、 prototype,同Spring1.x中的singleton=”false”

          ?? 3、 request,這種beanwebrequest范圍內(nèi)有效,即每次請(qǐng)求時(shí)都會(huì)產(chǎn)生一個(gè)實(shí)例。只用于web程序中。
          ?? 4、
          session,這種beanwebsession范圍內(nèi)有效。只用于web程序中
          ?? 5、
          global session,這種beanweb的全局session范圍內(nèi)有效。只用于web portlet框架中。

          下面通過(guò)一個(gè)例子來(lái)說(shuō)明單例beanprototype bean的使用。在例子中,我們創(chuàng)建一個(gè)DateTime類,在其構(gòu)造方法中獲取當(dāng)前的系統(tǒng)時(shí)間,并存貯于date成員之中。然后利用該類定義兩個(gè)bean,一個(gè)為單例bean,一個(gè)為prototype bean。利用線程,兩次調(diào)用getBean方法從IoC容器中獲取這兩個(gè)bean的實(shí)例,并將存儲(chǔ)于其中時(shí)間打印出來(lái)。為了便于測(cè)試,在兩次調(diào)用getBean方法之間讓線程暫停小段時(shí)間。這樣,如果是單例bean,由于在容器中只是實(shí)例化一次,那么兩次調(diào)用顯示的時(shí)間應(yīng)當(dāng)相同,prototype則不一樣。通過(guò)其返回時(shí)間是否一支來(lái)查看受管bean是否重新被實(shí)例化。
          ?? 1、 新建一個(gè)java工程,為添加Spring開(kāi)發(fā)能力后,建一個(gè)ioc.test

          2、創(chuàng)建一個(gè)類DateTime,添加一Date類型的成員,并添加Geter方法。修改其構(gòu)造方法,讓其在構(gòu)造方法中獲取當(dāng)前系統(tǒng)時(shí)間,并存貯與date屬性中。代碼如下:

          ?1?package?ioc.test;
          ?2?
          ?3?import?java.util.Calendar;
          ?4?import?java.util.Date;
          ?5?
          ?6?public?class?DateTime?{
          ?7?????private?Date?date;
          ?8?????DateTime(){
          ?9?????????this.date?=?Calendar.getInstance().getTime();
          10?????}
          11?????public?Date?getDate()?{
          12?????????return?date;
          13?????}
          14?}
          15?

          3、新建一Thread類的子類MyThread,重載run方法,在run方法中兩次調(diào)用getBean方法從容器獲取bean實(shí)例,然后分別將存貯與bean實(shí)例中的時(shí)間打印出來(lái)。代碼如下:

          ?1?package?ioc.test;
          ?2?import?org.springframework.context.ApplicationContext;
          ?3?public?class?MyThread?extends?Thread?{
          ?4?????
          ?5?????private?ApplicationContext?ac;
          ?6?????private?DateTime?dt;
          ?7?????private?String?bean;
          ?8?????MyThread(ApplicationContext?ac,String?bean){
          ?9?????????this.ac=ac;
          10?????????this.bean=bean;
          11?????}
          12?????
          13?????@Override
          14?????public?void?run()?{????????
          15?????????//第一次從容器取得bean
          16?????????dt?=?(DateTime)?ac.getBean(bean);
          17?????????System.out.println("Thread?Id:"?+?this.getId()+"?時(shí)間:"+dt.getDate());????????????????
          18?????????
          19?????????//線程暫停5秒
          20?????????try?{
          21?????????????sleep(1000?*?5);
          22?????????}?catch?(InterruptedException?e)?{
          23?????????}????????
          24?????????//第二次從容器取得bean
          25?????????dt?=?(DateTime)?ac.getBean(bean);
          26?????????System.out.println("Thread?Id:"?+?this.getId()+"?時(shí)間:"+dt.getDate());????????????????????}
          27?}
          28?

          4、編寫(xiě)Spring配置文件,配置兩個(gè)bean,一個(gè)singleton,一個(gè)prototype,如下:
          1<xml version="1.0" encoding="UTF-8"?>

          2<beans ……>

          3<bean id="singletonDateTime" class="ioc.test.DateTime" scope="singleton">bean>

          4<bean id="prototypeDateTime" class="ioc.test.DateTime" scope="prototype">bean>

          5beans>

          6

          5、編寫(xiě)一測(cè)試類TestMain,代碼如下:

          ?1?package?ioc.test;
          ?2?
          ?3?import?org.springframework.context.ApplicationContext;
          ?4?import?org.springframework.context.support.ClassPathXmlApplicationContext;
          ?5?
          ?6?public?class?TestMain?{
          ?7?????public?static?void?main(String[]?args)?{
          ?8?????????ApplicationContext?ac?=?new?ClassPathXmlApplicationContext(
          ?9?????????????????"applicationContext.xml");
          10?????????//測(cè)試單例bean
          11?????????MyThread?mt1?=?new?MyThread(ac,"singletonDateTime");
          12?????????mt1.start();
          13?????????
          14?????????//測(cè)試prototype?bean
          15?????????MyThread?mt2?=?new?MyThread(ac,"prototypeDateTime");
          16?????????mt2.start();
          17?????}
          18?}
          19?

          6、運(yùn)行測(cè)試類,結(jié)果如下:




          By:殘夢(mèng)追月
          posted on 2008-07-21 18:24 殘夢(mèng)追月 閱讀(4324) 評(píng)論(5)  編輯  收藏 所屬分類: Spring

          評(píng)論:
          # re: Spring中受管Bean作用范圍 2008-07-22 09:08 | 隔葉黃鶯
          你的程序代碼里沒(méi)有“當(dāng)前”,但是輸出里有“當(dāng)前”

          時(shí)間精確毫秒或納秒一級(jí)才能看得更明白,例如第一行和第二行輸出是否是同一個(gè) DateTime 實(shí)例。

          最好還是直接輸出實(shí)例實(shí)例的 HashCode(),也就是直接打印 bean 就是了。  回復(fù)  更多評(píng)論
            
          # re: Spring中受管Bean作用范圍 2008-07-22 10:25 | 殘夢(mèng)追月
          @隔葉黃鶯
          謝謝指教,是這樣子的,我把結(jié)果截圖后,發(fā)現(xiàn)當(dāng)前二字不妥,又修改了一下源代碼,把“當(dāng)前”去了,結(jié)果忘記重新截圖了。

          我就是故意讓線程多sleep一段時(shí)間,是為了看的清除一點(diǎn)點(diǎn)。如果只是sleep幾毫秒,結(jié)果就看不出來(lái)了。

          你說(shuō)的直接打印Bean的HashCode我到?jīng)]試過(guò),不過(guò)這也是一種思路。呵呵,反正重點(diǎn)不在于此,在于理解了受管Bean的聲明周期,對(duì)不?  回復(fù)  更多評(píng)論
            
          # re: Spring中受管Bean作用范圍 2008-07-22 11:03 | 隔葉黃鶯
          因?yàn)閳?zhí)行完 mt1.start() 之后,馬上就能去執(zhí)行 mt2.start() 方法,相差不了一秒

          所以從輸出上無(wú)法分辨出第一行和第二行打印的是否是同一個(gè) bean,不知我說(shuō)明白了沒(méi)有。  回復(fù)  更多評(píng)論
            
          # re: Spring中受管Bean作用范圍 2008-07-22 12:52 | 殘夢(mèng)追月
          @隔葉黃鶯
          謝謝!
          這個(gè)啊?我想你可能沒(méi)看明白我的意思,在線程mt1 中,執(zhí)行的是單例bean,線程mt2 是prototype Bean,這兩個(gè)線程是互不相關(guān)的。我們只是需要比較:
          1、第一行和和第三行時(shí)間相同。因?yàn)槭菃卫齜ean,只是實(shí)例化一次碼。
          2、第二行和第四行時(shí)間不同,是prototype Bean,在線程中調(diào)用了兩次,實(shí)例化了兩次。

          我把兩次調(diào)用放到一個(gè)線程里的,而不是兩個(gè)不同的線程。
          線程類的run方法里很明白了。  回復(fù)  更多評(píng)論
            
          # re: Spring中受管Bean作用范圍 2008-07-22 12:55 | 殘夢(mèng)追月
          @隔葉黃鶯
          不過(guò)我確實(shí)應(yīng)該在線程的Run方法中打印出bean的hashcode.便于分辨.謝謝!  回復(fù)  更多評(píng)論
            
          主站蜘蛛池模板: 榆中县| 日喀则市| 霍邱县| 罗江县| 平安县| 巩义市| 怀远县| 邛崃市| 雷波县| 慈利县| 河池市| 长宁区| 长白| 北流市| 新民市| 台中市| 吉安县| 石泉县| 德化县| 绥江县| 中牟县| 拉萨市| 樟树市| 新津县| 宣威市| 油尖旺区| 额尔古纳市| 明水县| 吉安县| 衡东县| 麟游县| 察隅县| 湄潭县| 贵港市| 蒲江县| 双鸭山市| 敖汉旗| 阿合奇县| 都兰县| 乐业县| 东辽县|