Spring中bean的scope有六種:singleton,prototype,request,session,global session,application。此外,使用者還可以自定義scope。還有一種scope是thread類型的,但是預設沒有啟用。
singleton是預設的scope。全局範圍内隻有一個bean被托管,所有對它的請求或者引用都是指向的這個Spring容器内的唯一執行個體。
換句話說,當你定義了一個singleton的bean以後,Spring 的 IoC容器會建立且僅建立一個對象的執行個體。這個執行個體會儲存在singleton bean的緩存中,所有的請求和引用都傳回這個緩存中的對象。
Spring的singletonbean概念不同于24種設計模式(Gang of Four, GoF)中的單例模式,單例模式在編碼中定義了對于每一個 ClassLoader 都隻會産生唯一執行個體,而Spring的singleton bean是在每一個Spring容器中産生唯一bean。
要使用xml定義bean,可以這樣
<bean id="accountService" class="com.foo.DefaultAccountService"/>
或
<bean id="accountService" class="com.foo.DefaultAccountService" scope="singleton"/>
明确指明singleton的scope有些多餘,不過可以接受。
prototype的scope是另一種常用的bean,是和singleton相對的。對于每一次請求該bean,spring都會建立一個新的執行個體。prototype的是有狀态bean,singleton是無狀态bean。
使用xml建立方式如下
<bean id="accountService" class="com.foo.DefaultAccountService" scope="prototype"/>
不同于其他scope,Spring不會管理prototype的bean。盡管所有scope的bean初始化回調都會被調用,但是對于prototype的bean,Spring不會調用其銷毀回調。必要的時候,使用者需要同代碼來銷毀其。
request和session已經global session都是web模式下才能使用的。如果使用ClassPathXmlApplicationContext初始化容器,會報錯IllegalStateException。
要是有這些scope,需要做一些額外的配置(上述兩種不需要)。在Spring MVC中,如果通過DispatcherServlet 或 DispatcherPortlet 過濾請求就不需要更多修改了,因為它們包含了相關的狀态。
如果沒有使用Spring 的MVC,比如使用了Struts,對于Servlet 2.5需要注冊org.springframework.web.context.request.RequestContextListener。對于Servlet 3.0以上,可以通過WebApplicationInitializer代碼配置這個監聽器。在web.xml中配置方式如下:
<web-app>
...
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
...
</web-app>
如果容器不支援這種方式,可以使用過濾器RequestContextFilter:
<web-app>
...
<filter>
<filter-name>requestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
...
</web-app>
application的scope和singleton的很像,不過有兩點差別:application的是對于每個ServletContext産生一個執行個體而非每個Spring容器;另外它是ServletContext可見的。