Spring中受管Bean作用範圍

By:殘夢追月

(殘夢追月原創,轉載請註明,原載與我的blogjava博客)
http://www.blogjava.net/cmzy/archive/2008/07/21/216415.html

jsp中,使用jsp標籤來引用JavaBean,可以通過其scope屬性的值來確定該標籤引用JavaBean的作用範圍。在Spring IOC容器中,由它管理的Java Bean也具有作用範圍。

Spring1.x版本中,標籤有一個屬性singleton,取值爲布爾類型。如果將其設置爲true,那麼容器之中只存在一個該bean的共享實例,當其他的任何Bean依賴該bean時,只要請求的id與該beanid相同,容器就將該bean的實例注入到請求的bean中。換言之,Spring IoC容器只是創建該bean的一個唯一實例,並把它存存貯在容器的單例緩存中,在需要時纔將其取出。這樣的受管bean稱之爲“單例bean”。

如果設置爲false,那麼每當其他bean依賴此bean時,容器則會重新實例化一個該bean對象,爲其注入。

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

2、一般來說,對於無狀態的bean使用單例模式,對於有狀態的bean使用prototype模式。

3、Spring IoC容器不會維護prototype類型的bean的整個聲明週期,容器在實例化、配置、注入之後就把它扔給調用者,然後就不管了。

4、如果一個單例bean computer引用了一個prototype類型的bean host,由於單例bean只初始化一次,所以不能保證每次調用computerhost都是最新的。解決辦法是使用lookup方法注入。

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

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

   3、 request,這種beanwebrequest範圍內有效,即每次請求時都會產生一個實例。只用於web程序中。
   4、
session,這種beanwebsession範圍內有效。只用於web程序中
   5、
global session,這種beanweb的全局session範圍內有效。只用於web portlet框架中。

下面通過一個例子來說明單例beanprototype bean的使用。在例子中,我們創建一個DateTime類,在其構造方法中獲取當前的系統時間,並存貯於date成員之中。然後利用該類定義兩個bean,一個爲單例bean,一個爲prototype bean。利用線程,兩次調用getBean方法從IoC容器中獲取這兩個bean的實例,並將存儲於其中時間打印出來。爲了便於測試,在兩次調用getBean方法之間讓線程暫停小段時間。這樣,如果是單例bean,由於在容器中只是實例化一次,那麼兩次調用顯示的時間應當相同,prototype則不一樣。通過其返回時間是否一支來查看受管bean是否重新被實例化。
   1、 新建一個java工程,爲添加Spring開發能力後,建一個ioc.test

2、創建一個類DateTime,添加一Date類型的成員,並添加Geter方法。修改其構造方法,讓其在構造方法中獲取當前系統時間,並存貯與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方法中兩次調用getBean方法從容器獲取bean實例,然後分別將存貯與bean實例中的時間打印出來。代碼如下:

 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()+" 時間:"+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()+" 時間:"+dt.getDate());                    }
27 }
28 

4、編寫Spring配置文件,配置兩個bean,一個singleton,一個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、編寫一測試類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         //測試單例bean
11         MyThread mt1 = new MyThread(ac,"singletonDateTime");
12         mt1.start();
13         
14         //測試prototype bean
15         MyThread mt2 = new MyThread(ac,"prototypeDateTime");
16         mt2.start();
17     }
18 }
19 

6、運行測試類,結果如下:




By:殘夢追月
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章